how can set cookie with Ajax/jQuery? - javascript

i have ajax function like below:
$.ajax({
url:"cookie.php",
type: 'post',
data: {'ok': val},
success:function(data) {
alert(data);
}
});
and my cookie.php for setcookie is:
$name = "mySite";
$value = "stackoverflow.com";
setcookie($name, $value, time() + (86400 * 30), "/");
echo $name."=".$value;
with my ajax function mySite=stackoverflow.com show in my page but cookie not set in browser. why?

Cookies are set using the HTTP Set-Cookie header, sent in the HTTP response when a page first loads.
This header instructs the browser to store the cookie and send it back in future requests to the server.
When you set the cookie with ajax, the browser doesn't reload the current page, and no new headers are sent.
Instead, a new request is sent in the background with XMLHttpRequest, and the cookies are never added to the current page headers, as that page newer reloads and receives the header containing the cookie.
You have to reload the page and get a new set of headers to see the new cookies added in PHP.
There's also the option of setting the cookies in javascript, then they would be visible in the browser right away.
document.cookie="mySite=stackoverflow.com; expires=Thu, 18 Dec 2015 12:00:00 UTC; path=/";

Related

How to set samesite=none

My browser page is loaded from my server but must acquire data from another - third party.
My code to make the very first call to this third party site is:
var Vurl = "https://" + info.server + "/rest/system/session";
var Body = JSON.stringify({name: 'session', value: info.session});
var xhr = new XMLHttpRequest();
xhr.open('POST', Vurl, true);
xhr.withCredentials = true;
xhr.send(Body);
xhr.onreadystatechange = function()
{
if(this.readyState == this.HEADERS_RECEIVED)
{
// Get the raw header string
var headers = xhr.getAllResponseHeaders();
}
}
I have to place the following someplace but I don't know where. All the searches in google just state it's required but not how to implement it.
cookie('session', info.session, { sameSite: 'none', secure: true });
Can you show/tell me the proper way to set the "samesite" when working with XMLHttpRequest as shown above.
Thanks
More Info:
The call shown is sending information to the third party server. The third party reply has a "session" cookie that must replace the existing session cookie. From what I can find - chrome will not update the cookie from the third party reply unless "withCredentials" is set to true, samesite=none, and secure. My understanding is that all of that is set, then chrome will update the cookie in the browser.
My issue to resolve is that following the call, I open a websocket to the third party and it expects a "session" cookie in the header to be the same as returned from the XMLHttpRequest.
Is my understanding correct? How do I implement?
More Added - Chrome warning I'm trying to implement
A cookie associated with a cross-site resource at http://hinkle1.sipworxx.com/ was set without the SameSite attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with SameSite=None and Secure. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032
It is just a cookie:
Set-Cookie: flavor=choco; SameSite=None; Secure
In your example:
cookie('SameSite', 'None');
cookie('Secure');
Source:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite

PHP Session is empty on first Ajax call

I have a page that has some heavy content and takes around 1.5 minutes to fully load. I have added the retrieve data on scroll functionality where am calling an ajax request when the user scrolls to retrieve data.
I have wrapped the data retrieval behavior to a function handleEventsLoad() and called this function on load trying to cover the case where the user scrolls before the page fully loads reaching the end:
$(document).ready(function()
{
$(window).scroll(function()
{
handleEventsLoad();
});
handleEventsLoad();
});
The ajax request is called properly, though, the first time this request is called I cannot read any session data at PHP level in $_SESSION knowing that the session is being set on page load and if I print it in the HTML I can see its value.
After the page fully loads the first time and I refresh the page, the same request is called but this time I can read the session data properly and the auto load on scroll functions as expected (the difference here is that all the data have been cached and the pages takes 7 sec to load).
Does the loading process have anything to do with reading the session at ajax call?
Here is a sample of the ajax :
function handleEventsLoad()
{
if($('#sidebar').length > 0
&& $(window).scrollTop() >= $('#sidebar').offset().top + $('#sidebar').outerHeight() - window.innerHeight)
{
$.ajax({
url: "ajaxUrl.php",
type: 'GET',
dataType: 'json',
data: {/* passing some data */},
success:function(data)
{
// some code here
},
error: function(xhr, status, error)
{
var err = eval("(" + xhr.responseText + ")");
console.log(err.Message);
}
});
}
}
ajaxUrl.php
<?php
session_start();
print_r($_SESSION);
return;
?>
UPDATE
Please find below the difference between HTTP requests between the first and second ajax calls:
Request:
First Call:
Connection: keep-alive
Second Call:
Cookie: _ga=GA1.2.1253088293.1457289524; _gat=1; PHPSESSID=79c38493322374f1bc19541f4c538b02
Connection: keep-alive
Cache-Control: max-age=0
Response:
First Call:
Set-Cookie: PHPSESSID=79c38493322374f1bc19541f4c538b02; expires=Mon,
07-Mar-2016 18:38:41 GMT; path=/; domain=www.mydomain.com; secure;
HttpOnly PHPSESSID=79c38493322374f1bc19541f4c538b02; expires=Mon,
07-Mar-2016 18:38:41 GMT; path=/
Second Call:
Set-Cookie: PHPSESSID=79c38493322374f1bc19541f4c538b02; expires=Mon, 07-Mar-2016 18:40:06 GMT; path=/

Header cookies not being set by another subdomain?

I have two subdomais "api.domain.com" and "web.domain.com".
Now "web.domain.com" is web page written in html/javascript and "api.domain.com" is a simple restful API server written in php.
"api.domain.com" sets certain cookies in the header as follows
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Credentials: true");
setcookie("TestCookie", "Some Value", time()+3600, "/", ".domain.com", 0);
Now, when I make an ajax call (using jQuery.ajax() ) from "web.domain.com" to "api.domain.com", the response headers contain
Set-Cookie:abc=802691344656c1d0899c4a74.87956617; expires=Mon, 16-May-2016 21:00:09 GMT; path=/; domain=domain.com,
so i guess a cookie should be set in the client browser at "web.domain.com".
The next time I make another request to "api.domain.com" from "web.domain.com", shouldn't this cookie go as part of the request headers?
However, when I inspect the $_COOKIE array at "api.domain.com", i don't see this cookie! Does that mean the cookie never got set in the client ("web.domain.com") at the first place? What am I doing wrong?
Using the withCredentials header (as suggested by #charlietfl) worked for me. I had to make one more modification in the server as well.
So here's what I did.
In web.domain.com , while maqking the Ajax request, I added withCredentials: true , like this
$.ajax({
// The Url for the request
url : ajaxUrl,
// The data to send (will be converted to a query string)
data : ajaxData,
xhrFields: {
// To allow cross domain cookies
withCredentials: true
},
...
});
In api.domain.com , I set some headers like this :
header("Access-Control-Allow-Origin: *");
However, I was still unable to get any response. I got this error instead
Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true.
So i simply set the header to the origin domain, like so :
$http_origin = $_SERVER['HTTP_ORIGIN'];
if (substr($input, -10) == 'domain.com') { // To check if request is always from a subdomain of 'domain.com'
header("Access-Control-Allow-Origin: $http_origin");
}
That fixed the issue.

jQuery cookie not being passed from HTTPS page to another HTTPS page

I am trying to send a cookie from one HTTPS page to another HTTPS page with jQuery cookies.
I set the cookie like so one page 1:
$.cookie('name', variable, { expires: 300 , secure:true});
And then on the next page, I try to get it like so:
console.log( $.cookie('name') );
No dice... is what I am trying to do illegal or immoral in some way?
If it helps, the pages are:
Page 1
Page 2 can be reached by clicking on any of the "Try it Free" buttons.
You can set cookie with domain path:
$.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
You can read that here:
JQuery Cookie values not maintained while moving from http to https
you can set and get cookie by javascript as well that works fine on https server
set cookie:
document.cookie="username=John Doe";
get cookie:
var x = document.cookie;
delete cookie:
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
you can get help from:
http://www.w3schools.com/js/js_cookies.asp

Force a reload of page in Chrome using Javascript [no cache]

I need to reload a page using JavaScript and ensure that it does not pull from the browser cache but instead reloads the page from the server.
[As elements of the page will have changed in the interim]
On IE and FF I found that the following code worked fine;
window.location.reload(true);
However it does not work on Chrome or Safari.
I tried the following, but also to no avail;
window.location.replace(location.href);
document.location.reload(true);
document.location.replace(location.href);
Is there a solution to this issue?
Findings
After looking into this I have found that this issue is HTTP Protocol handling;
Chrome sends a request with Pragma: no-cache HTTP field
Server responds with Last-Modified: DATE1 field
JS uses location.reload(true) to force a reload from server not cache
Chrome sends a request with If-Modified-Since: DATE1 field
Server responds with HTTP Status 304 Not Modified
The server application is at fault for not noticing the state change in the dynamic page content, and thus not returning a 200.
However, Chrome/WebKit is the only browser that sends a If-Modified-Since field when the JS location.reload(true) is called.
I thought I would put my findings here in-case someone else comes across the same issue.
You can use this hack:
$.ajax({
url: window.location.href,
headers: {
"Pragma": "no-cache",
"Expires": -1,
"Cache-Control": "no-cache"
}
}).done(function () {
window.location.reload(true);
});
To ensure the page isn't loaded from cache you can add some unique number to query:
window.location = location.href + '?upd=' + 123456;
You also can use date instead of 123456
This is what I do to ensure my application file is force reloaded on chrome:
var oAjax = new XMLHttpRequest;
oAjax.open( 'get', '/path/to/my/app.js' );
oAjax.setRequestHeader( 'Pragma', 'no-cache' );
oAjax.send();
oAjax.onreadystatechange = function() {
if( oAjax.readyState === 4 ) {
self.location.reload();
}
}
Try window.location = window.location
Great findings! I just encountered the same issue and this really helps a lot!
However, in addition to your finding, it seems that Chrome always sends a GET request for location.reload()...IE/FF is repeating the last request instead.

Categories