在跨域 ajax 请求后保留 cookie
Keeping the cookie after a cross-domain ajax request
在10.0.0.1
上的JavaScript应用程序尝试使用跨域ajax调用对其用户进行身份验证。
请求如下所示:
function test(again){
$.ajax({
type: 'GET',
url: 'http://example.com/userinfo',
dataType: 'json',
success: function(userinfo){
if(again)
test(false);}});}
test(true);
来自服务器的第一个响应尝试设置 cookie:
Access-control-allow-origin:http://10.0.0.1
Set-Cookie:PHPSESSID=uuj599r4k1ohp48f1poobil665; expires=Sat, 28-Jan-2012 17:10:40 GMT; path=/
但是第二个请求不包括此cookie,也不包括对该域的任何其他ajax请求。
我不是在尝试读取另一个域的cookie,我只是希望另一个域上的应用程序能够设置和读取自己的cookie。
这可能吗?
我已经在Chrome和Firefox 9中进行了测试。
服务器应该设置标头:
response.Headers.Add("Access-Control-Allow-Credentials", "true");
客户端设置为:
xhrFields: {
withCredentials: true
}
只要您使用支持 CORS 的浏览器,AJAX 请求上的 cookie 就应该可以工作。但是你必须把XMLHttpRequest
withCredentials
设置为真。
请参阅: withCredentials属性
我不使用 JQuery,但这里有一个专门处理通过 JQuery 设置withCredentials
的问题。
使用跨域帖子发送凭据?
不可以,Cookie 不能跨域共享。假设浏览器支持Access-Control-*
标头,对于使用 AJAX 调用,可以规避同源策略,但对于 cookie,则没有办法。
+Darin Dimitrov怀疑"浏览器没有保存cookie,因为它来自另一个域,而不是托管此调用源页面的域"。
但是,当使用 JSONP 时,cookie 会根据需要进行设置,但 JSONP 仅适用于 GET 请求。
我的解决方案是通过在<script>
中加载以下 php 文件来检索 cookie(PHP 会话 ID(:
<? echo $_GET['callback'] . '("' . session_id() . '")'; ?>
并将会话 ID 作为请求变量传递到所有跨域 POST 请求中。
我需要使用 AJAX 和 PHP 将 cookie 从多个子域传递到单个 API 域。
这是挑战和解决方案:
1 - api.example.com 上的后端 PHP。
2 - 多个 JS 前端,如 one.example.com、two.example.com 等。
3 - Cookie 需要双向传递。
4 - 从多个前端到 PHP 后端的 AJAX 调用 api.example.com
5 - 在PHP中,我不喜欢使用$_SERVER["HTTP_ORIGIN"],在我看来并不总是可靠/安全的(我有一些浏览器的HTTP-ORIGIN总是空的(。
在具有单前端域的 PHP 中执行此操作的正常方法是使用以下方式启动 PHP 代码:
header('Access-Control-Allow-Origin: https://one.example.com');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
header('Access-Control-Allow-Credentials: true');
在 one.example.com 域上的JS中:
jQuery.ajax({
url: myURL,
type: "POST",
xhrFields: {withCredentials: true},
dataType: "text",
contentType: "text/xml; charset='"utf-8'"",
cache: false,
headers: "",
data: myCallJSONStr,
success: function(myResponse) {.....}
但是,这不可行,因为我使用多个子域来调用我的 API 域。
并且此解决方案将不起作用,因为我想传递cookie:
header('Access-Control-Allow-Origin: *');
它与JS网站上的传递cookie设置冲突:
xhrFields: {withCredentials: true}
这是我所做的:
1 - 使用 GET 参数传递子域。
2 - 在PHP中对主域进行硬编码,以便只允许(所有(子域。
这是我的解决方案的 JS/JQuery AJAX 部分:
函数 getSubDomain(({
let mySubDomain = "";
let myDomain = window.location.host;
let myArrayParts = myDomain.split(".");
if (myArrayParts.length == 3){
mySubDomain = myArrayParts[0];
}
return mySubDomain;
}
在 AJAX 调用中:
let mySubDomain = getSubDomain();
if (mySubDomain != ""){
myURL += "?source=" + mySubDomain + "&end"; //use & instead of ? if URL already has GET parameters
}
jQuery.ajax({
url: myURL,
type: "POST",
xhrFields: {withCredentials: true},
dataType: "text",
contentType: "text/xml; charset='"utf-8'"",
cache: false,
headers: "",
data: myCallJSONStr,
success: function(myResponse) {.....}
最后,PHP部分:
<?php
$myDomain = "example.com";
$mySubdomain = "";
if (isset($_GET["source"])) {
$mySubdomain = $_GET["source"].".";
}
$myDomainAllowOrigin = "https://".$mySubdomain.$myDomain;
$myAllowOrigin = "Access-Control-Allow-Origin: ".$myDomainAllowOrigin;
//echo $myAllowOrigin;
header($myAllowOrigin);
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
header('Access-Control-Allow-Credentials: true');
重要提示,不要忘记为所有子域设置 cookie,在这种情况下,cookie 的域将是:.example.com(因此在主域前面有一个点(:
<?php
//////////////// GLOBALS /////////////////////////////////
$gCookieDomain = ".example.com";
$gCookieValidForDays = 90;
//////////////// COOKIE FUNTIONS /////////////////////////////////
function setAPCookie($myCookieName, $myCookieValue, $myHttponly){
global $gCookieDomain;
global $gCookieValidForDays;
$myExpires = time()+60*60*24*$gCookieValidForDays;
setcookie($myCookieName, $myCookieValue, $myExpires, "/", $gCookieDomain, true, $myHttponly);
return $myExpires;
}
此解决方案允许我从 example.com 上的任何子域调用 api.example.com 上的 API。
注意:对于只有一个调用子域的情况,我更喜欢使用 .htaccess 来设置 CORS 而不是 PHP。以下是仅 one.example.com 调用 api.example.com 的.htaccess(linux/apache(示例:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "https://one.example.com"
Header set Access-Control-Allow-Headers "Origin, Content-Type, X-Auth-Token"
Header set Access-Control-Allow-Credentials "true"
</IfModule>
并将此 .htaccess 放在 api.example.com 的根目录中。
- 分派点击事件并保留击键修饰符
- 在jquery中为显示/隐藏设置cookie
- 按下按钮时保存cookie
- 像cookie这样的全局变量,它在回发后保留值,但应该为不同的实例保存不同的值(选项卡/窗口)
- 如何为XmlHttpRequest保留多组cookie
- 跨多个页面保留 Cookie 表单值
- 如何在Meteor中的多个帖子请求中保留cookie
- 在跨域 ajax 请求后保留 cookie
- 我的代码是否有任何错误,不允许在关闭应用程序后在移动浏览器上保留cookie
- Javascript代码Cookie保留/保留替代Css
- 保留类的页面加载与Javascript Cookie
- 无法使用jquery.cookie保留复选框值
- 在一个页面上设置的Cookie不会在使用Javascript的其他页面上保留
- 如何在javascript中清除cookie而不保留任何到期时间
- 浏览器为单个cookie名称-值对保留多个值
- 使用cookie在网站上保留样式表偏好
- 即使在浏览器关闭后仍保留cookie
- 当按下返回按钮时,保留SESSION值或Cookie
- 如何在不使用jQuery或javascript更改浏览器设置的情况下保留cookie
- 在页面刷新时保留 Cookie 存储区的范围值