Cannot access cookies in Chrome, works properly in Firefox - php

Basic situation and basic relevant info:
I have a php code that executes before the opening <doctype> tag. The hope was to (if necessary) send a redirect based on user's browser's language preferences before anything else loads.
The script attempts to do two things based on highest supported language preference:
Use php: setcookie() to create a cookie with the two-letter language code.
Example cookie name = value: x_language = es
Use php: header("Location: " . $requestedSite); to redirect to a subdomain,
Example domain: es.domain.com
Example:
if (isset($_COOKIE['x_language'])) {
-Determine correct subdomain based on cookie value-
-If not currently on that subdomain, redirect to it-
} else {
setcookie('x_language','es',time() + 31536000 ,'/','.domain.com' );
header("Location: " . $requestedSite);
}
The problem:
Firefox works perfectly. Chrome (and other browsers) fail to recognize the cookies at all.
I've boiled it down to this:
print_r($_COOKIE) works properly in Firefox, and returns a lovely, populated array.
print_r($_COOKIE) fails in Chrome, and returns an empty array.
This is the core of the problem, my function doesn't recognize the existence of a cookie because Chrome doesn't.
I've made sure every browser accepts cookies.
I've checked dev tools to make sure the cookie is in place on all browsers, (it is).
I realize a cookie's value isn't available until the next page load, but that isn't an issue here. Even after it is set, it won't read.
There is no output above the initial setcookie();
So how do I get Chrome (and other browsers) to recognize its own cookies?! Does anyone know why this would all work flawlessly on Firefox but fail elsewhere?
On a lark I decided to try this. I created a file that only contains:
<?php
print_r($_COOKIE);
?>
Again, I see the cookie array in Firefox. Meanwhile, in Chrome, IE, Opera, Safari, I get an empty array. Could this be a server issue?

OP returns with answer:
Alright, I'm adding this as an 'Answer' in case anyone else comes across this (totally bizarre) behavior and lands here:
It turns out my hosting provider was doing some seriously aggressive caching with my WordPress site that I was unaware of.
At the time I posted my question, I didn't think being on WordPress was relevant, but apparently it was.
Basically it was doing this:
With a clean Cache:
Visitor 1 visits the site.
The php processes and produces output as expected.
Visitor 1 is served php output (based on his browser's parameters and such).
Visitor 2 visits the site. Visitor 2 sees *Visitor 1's version of the site.
The php is processed once and only once per Cache-clear.
This caching behavior meant that accessing cookies through php was simply not going to work right, but accessing them with Javascript WOULD work.
(Important note: It turns out the above-stated caching behavior is disabled for any user viewing the site while logged into wordpress, and this is common behavior for WordPress Cache plugins. That is why I was seeing different behavior in Firefox than I saw in other browsers, because I was actively logged in with Firefox. This could be a helpful piece of information for someone out there.)
My solution:
Use Javascript to run an AJAX query to a .php file which would process the language preferences of the visitor and return the output as a 2-character code, (i.e. 'en' 'es' 'pt' 'de', etc).
Using AJAX to call php allowed me to use php's server-side access to a browser's language preferences while circumventing the super-agro caching of my host.
I hope this helps someone! And thanks to everyone who tried to help me out with this.

I was not having this problem with the code below. I was able to go to example.com and be redirected immediately to en.example.com and see the cookie in $_COOKIES. If I used en.example.com?set=fr I would be redirected to fr.example.com every time I tried example.com. Hopes this is what you were looking for!
<?php
print_r($_COOKIE);
if(isset($_GET['nuke'])) {
setcookie('x_language','',time()-1000,'/','.example.com');
echo 'It has been nuked!';
exit;
} else if(isset($_GET['set'])) {
setcookie('x_language',$_GET['set'],time() + 31536000, '/','.example.com');
$_COOKIE['x_language'] = $_GET['set'];
}
if (isset($_COOKIE['x_language'])) {
$redirect = $_COOKIE['x_language'].'.example.com';
if($_SERVER['HTTP_HOST'] != $redirect)
header('Location: http://'.$redirect);
} else {
setcookie('x_language','en',time() + 31536000,'/','.example.com');
$redirect = 'http://en.example.com';
header('Location: '.$redirect);
}
echo '<br />Cookie: '.$_COOKIE['x_language'].' Domain: '.$_SERVER["HTTP_HOST"];
?>

Related

Cookies not read in IE

Im having a strange problem.
I have a subdomain where a customer comes in with a specific URL
When the customer is recognized I set a cookie and redirect them to the main domain.
there I check for this cookie to hide some elements.
This is working great in Chrome, Firefox and even Edge on Microsoft, but not in IE11 and chrome on Apple machines.
When I type document.cookie in the IE console, I can see the cookie.
I display a cookie found message in the console which I can see in chrome etc. but not in IE.
So it looks like IE can't find the cookie, while it is actually there.
Is there someone who can explain this behaviour?
I finally found the problem.
When checking for the existence of the cookie, at first I used this line of jQuery code.
if (document.cookie.split(';').filter((item) => item.includes('cookiename=')).length) {
console.log('cookie found');
}
I briefly saw an error message in IE that pointed to this line of code.
so, I changed it to the, btw much easier, line
if (document.cookie.indexOf("cookiename=") != -1) {
console.log('cookie found');
}
which IE has no problem with.

PHP's $_SESSION overwritten - only in Firefox (Mozilla)

Within my site, I use the variable $location that keeps track of the page the user is viewing. At the end of index.php, the variable is copied into the $_SESSION array, so that upon the next request I know where the user was last time (I use it for generating "back" links). So index.php goes roughly like this:
$location = GetLocation(); // gets user location by processing $_POST and $_GET
if(!isset($_SESSION['last_location'])) $_SESSION['last_location'] = SomeMeaningfulLocation();
.
.
OutputPage(); // renders the page based on $location
.
.
$_SESSION['last_location'] = $location;
So in OutputPage(), the $_SESSION['last_location'] variable can be used for generating "back" links.
The problem is: this code works perfectly with MSIE, Chrome and Safari. It doesn't, however, work with Firefox nor with SeaMonkey (which I like to use for web development). In these browsers, the "back" links always point to the frontpage.
Other facts that might be useful:
Session data is stored in files, server date and time is set right
I've already tried playing with cache settings (header('Cache-control: ...') etc.) with no difference
I've tried disabling network.prefetch-next in the Firefox/Seamonkey config (no difference)
The SomeMeaningfulLocation() function does NOT return frontpage location - so to eliminate the possibility the session is 'forgotten' and re-initialized upon each request - which is also excluded by the fact that...
... other session variables work just fine (but this one is different in that its content is automatically updated upon each request)
Nothing wrong can be seen in the apache access/error logs (it is just the same as with the other browsers)
when i check the $_SESSION['last_location'] value just after the assignment (in the very end of index.php), it has the correct value. When i check it in the very beginning of index.php, it is already overwritten with the frontpage's location (I repeat: only in Mozilla. In other browsers, these checks show the correct, expected values!)
Thanks in advance, I'm out of ideas :-)

Zend framework session lost

I have a register form, when user sign up, it will redirect him to his page.
All work fine in firefox and chrome, but in internet explorer. It looks like after the user information is saved, the session went off and it won't redirect the user to his page.
How can I fix this issue on IE?
$user = $this->_helper->model('Users')->createRow($signupForm->getValues());
if ($user->save())
{
Zend_Session::rememberMe(186400 * 14);
Zend_Auth::getInstance()->getStorage()->write($user);
$user->sendSignUpEmail();
$this->getHelper('redirector')->gotoRoute(array(), 'invite');
return;
}
I'v got a similary problem to create session in iframe on IE before a redirection, and this works for me :
Try to put in the Zend Action :
$response = $this->getResponse();
$response->setHeader('P3P', 'CP="CAO PSA OUR"', true);
See What does header('P3P: CP="CAO PSA OUR"'); do?
You seems to keep posting variations of the same question. There's nothing in your code which should work differently on different browsers. You need to debug this to see how far IE is getting, that will help you identify the root cause of the problem.
So, do some debugging to try and answer these questions:
Does $user->save() return true? (i.e. does IE go into the if statement)
If it does go into the if, what is in $user? Try var_dump($user);exit; inside the if to see what you get
Does $user->sendSignUpEmail(); get called?
If it gets to the redirect part, what headers are being sent? (You should be able to check this using IE's developer tools)
If you are testing in IE on a different machine to the one with browsers that are working, also check the system clock, as incorrect date/time can cause sessions to be expired immediately.

How to access offsite referer (and first page visited on site) via PHP on Wordpress site

I'm trying to get three things into a hidden form field in a Wordpress page:
The last "offsite" page visited before someone visited any page on my site (e.g., quite possibly a Google page)
The first page they visited on my site
The last page on my site before they went to the form page
The third one is easy (just use ), but the first two are giving me problems.
I'm trying to save #1 and #2 by using session variables, so that on every page, in the header, I have the following code:
<?php
session_start();
if (! isset($_SESSION['offsite_referer'])) {
$_SESSION['offsite_referer'] = $_SERVER['HTTP_REFERER'];
}
if (! isset($_SESSION['first_page'])) {
$_SESSION['first_page'] = $_SERVER['REQUEST_URI'];
}
?>
Then further down I have, as test code (to be changed to input type=hidden etc. later):
<p>offsite_referer: <?= $_SESSION['offsite_referer'] ?></p>
<p>first_page: <?= $_SESSION['first_page'] ?></p>
(FWIW, I also have session_start() at the top of my wp-config.php. Yes, my site has register_globals turned off.)
For some reason, $_SESSION['offsite_referer'] always ends up as my home page, even when I hit the form page (/free-reports) directly via link from another site. Similarly, first_page always shows up as /
Yes, I'm clearing all my cookies etc. between attempts, to force a new session to be created.
This code used to work fine on my pre-Wordpress site, so I can only think it has something to do with WP, specifically perhaps WP's redirection (WP's mod_rewrite stuff in .htaccess)
I tried changing $_SESSION['offsite_referer'] = $_SERVER['HTTP_REFERER'] to wp_get_original_referer() but it seemed to have no effect.
Incidentally, if I access my form page (at /free-reports/) as the first page on my site (after clearing cookies etc.) and printing $_SERVER['HTTP_REFERER'], it correctly shows the last offsite page - even though $_SESSION['offsite_referer'] doesn't.
I'm pretty perplexed, and have spent a fair amount of time trying to figure it out on my own, so any help to solve this would be appreciated.
Chances are, you can't really get the referer URL since some browsers don't send that and some people disable that, but here's how you could do that and I'll give you some extra tips here:
//first of all, initialize the session
session_start();
//Now call logvisit() to log where the user is coming from
logvisit();
function logvisit() {
$_SESSION['offsite_referer'] = $_SERVER['HTTP_REFERER']);
$browser = $_SERVER['HTTP_USER_AGENT']; //Gets the browser the user is using
//If you want to test it (disable the code below if you don't want to print that information):
echo "Offsite referer: $_SESSION['offsite_referer']<br>";
echo "Browser: $browser<br>";
}
Then to destroy the session you can use unset($_SESSION['offsite_referer']);
This is how I usually do it, and it's often a tidy way to do it.
I believe scunliffe had the key to this, as I was using IE to do the testing.
It works fine now, which I attribute to actually closing and restarting IE (apparently just deleting cookies doesn't do it, as you'd think, even though that works fine in Firefox).
I also changed what I was doing slightly to just save the full in-site browse history in a session variable, rather than only first and last page on the site.
The code I ended up with was the following, which is just at the top of my theme's header.php file:
<?php
session_start();
if (! isset($_SESSION['site_history'])) {
$_SESSION['offsite_referer'] = $_SERVER['HTTP_REFERER'];
$_SESSION['site_history'] = '';
}
$_SESSION['site_history'] .= ($_SERVER['REQUEST_URI'] . ';');
?>
I originally had session_start() also in wp-config.php when I was trying to figure this out, but was able to remove it (leaving just the above code in header.php) and things still work fine.
In case anyone finds this page wanting to do something similar, I was able to access this info in my WP page by adding the following to my theme's functions.php:
function get_offsite_referer() { return $_SESSION['offsite_referer']; }
add_shortcode('offsite-referer', 'get_offsite_referer');
function get_site_history() { return $_SESSION['site_history']; }
add_shortcode('site-history', 'get_site_history');
and then to pass the info on my Wordpress page/form:
<input type="hidden" name="offsite_referer" value="[offsite-referer]" />
<input type="hidden" name="site_history" value="[site-history]" />
scunliffe, if you'd posted your comment as a "reply" I would have "accepted" it, since it was what most closely led me in the right direction, but as a comment I could only upvote it so that's what I did. Thanks!

CakePHP Auth Component "login" Method Failure in IE8 + Safari

I have a method in users_controller.php of my CakePHP project which is used to remotely log a user in through an AJAX call on a WordPress site. The method works flawlessly when called through Firefox, but when I attempt to call it either via AJAX or directly from the browser in IE8 or Safari, it simply will not log in. The Auth->login() method returns true as if everything is fine, but it does not log in. Any ideas?
function remoteLogin($key)
{
# this method should only be called via AJAX
$this->layout = 'ajax';
$matching_key = '***';
if($key == $matching_key)
{
# auto-login service account
$data['User']['username'] = '***';
$data['User']['password'] = $this->Auth->password('***');
$this->Auth->login($data);
}
}
Note: I have now confirmed that this method does not work in Opera either. I'm legitimately confused.
You might want to check your cookies and make sure they are being passed as you expect. Fiddler is helpful to see the http traffic as it goes by to figure out these AJAX issues.
Are www.domain.com and domain.com going to the same place?
If so this may be related to a CakePHP / IE issue I ran accross.
Delete any domain level cookies and see if it works.
In IE any domain cookies will take precidence over the subdomain cookies. So if you ever get a cookie going to domain.com and then later go to www.domain.com you can reset your session login, logout all day long but IE will ignore the www.domain.com cookies and continue to use the original domain.com one. I wrote a patch for an old version of Cake that would let you set/force the cookie scope to domain.com even when they are accessing the site as www.domain.com to get around this.
Don't now about IE8, but Safari does block cross-domain ajax, even between "siblings" under the same top domain. E.G. You can't have app.example.com load a div using ajax from helppages.example.com. Forget cookies, I am talking just plain html loaded using ajax.
I think the problem is your domain.
Ex: IE or some browser don't work if your domain like: abc_def.com, ...
Please check your domain and change it like abcdef.com => it'll be ok

Categories