ajax跨域访问cookie丢失的解决方法

本文介绍如何解决AJAX跨域访问时Cookie丢失的问题,通过设置withCredentials及Access-Control-Allow-Credentials实现跨域携带Cookie。

ajax跨域访问,可以使用jsonp方法或设置Access-Control-Allow-Origin实现,关于设置Access-Control-Allow-Origin实现跨域访问可以参考之前我写的文章《ajax 设置Access-Control-Allow-Origin实现跨域访问》

1.ajax跨域访问,cookie丢失

首先创建两个测试域名
a.fdipzone.com 作为客户端域名
b.fdipzone.com 作为服务端域名

测试代码

setcookie.php 用于设置服务端cookie

<?php
setcookie('data', time(), time()+3600);
?>

 
server.php 用于被客户端请求

<?php
$name = isset($_POST['name'])? $_POST['name'] : '';

$ret = array(
    'success' => true,
    'name' => $name,
    'cookie' => isset($_COOKIE['data'])? $_COOKIE['data'] : ''
);

// 指定允许其他域名访问
header('Access-Control-Allow-Origin:http://a.fdipzone.com');

// 响应类型
header('Access-Control-Allow-Methods:POST');  

// 响应头设置
header('Access-Control-Allow-Headers:x-requested-with,content-type');

header('content-type:application/json');
echo json_encode($ret);
?>

 
test.html 客户端请求页面

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <meta http-equiv="content-type" content="text/html;charset=utf-8">
  <script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
  <title> ajax 跨域访问cookie丢失的解决方法 </title>
 </head>

 <body>
    <script type="text/javascript">
    $(function(){

        $.ajax({
            url: 'http://b.fdipzone.com/server.php', // 跨域
            dataType: 'json',
            type: 'post',
            data: {'name':'fdipzone'},
            success:function(ret){
                if(ret['success']==true){
                    alert('cookie:' + ret['cookie']);
                }
            }
        });

    })
    </script>

 </body>
</html>

首先先执行http://b.fdipzone.com/setcookie.php, 创建服务端cookie。
然后执行http://a.fdipzone.com/test.html

输出

{"success":true,"name":"fdipzone","cookie":""}

获取cookie失败。

2.解决方法

客户端
请求时将withCredentials属性设置为true
使可以指定某个请求应该发送凭据。如果服务器接收带凭据的请求,会用下面的HTTP头部来响应。

服务端
设置header

header("Access-Control-Allow-Credentials:true");

允许请求带有验证信息


test.html 修改如下

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <meta http-equiv="content-type" content="text/html;charset=utf-8">
  <script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
  <title> ajax 跨域访问cookie丢失的解决方法 </title>
 </head>

 <body>
    <script type="text/javascript">
    $(function(){

        $.ajax({
            url: 'http://b.fdipzone.com/server.php', // 跨域
            xhrFields:{withCredentials: true}, // 发送凭据
            dataType: 'json',
            type: 'post',
            data: {'name':'fdipzone'},
            success:function(ret){
                if(ret['success']==true){
                    alert('cookie:' + ret['cookie']);
                }
            }
        });

    })
    </script>

 </body>
</html>

 
server.php 修改如下

<?php
$name = isset($_POST['name'])? $_POST['name'] : '';

$ret = array(
    'success' => true,
    'name' => $name,
    'cookie' => isset($_COOKIE['data'])? $_COOKIE['data'] : ''
);

// 指定允许其他域名访问
header('Access-Control-Allow-Origin:http://a.fdipzone.com');

// 响应类型
header('Access-Control-Allow-Methods:POST');  

// 响应头设置
header('Access-Control-Allow-Headers:x-requested-with,content-type');

// 是否允许请求带有验证信息
header('Access-Control-Allow-Credentials:true');

header('content-type:application/json');
echo json_encode($ret);
?>

按之前步骤执行,请求返回

{"success":true,"name":"fdipzone","cookie":"1484558863"}

获取cookie成功

3.注意事项

1.如果客户端设置了withCredentials属性设置为true,而服务端没有设置Access-Control-Allow-Credentials:true,请求时会返回错误。

XMLHttpRequest cannot load http://b.fdipzone.com/server.php. Credentials flag is 'true', but the 'Access-Control-Allow-Credentials' header is ''. It must be 'true' to allow credentials. Origin 'http://a.fdipzone.com' is therefore not allowed access.

2.服务端header设置Access-Control-Allow-Credentials:true后,Access-Control-Allow-Origin不可以设为*,必须设置为一个域名,否则回返回错误。

XMLHttpRequest cannot load http://b.fdipzone.com/server.php. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://a.fdipzone.com' is therefore not allowed access. The credentials mode of an XMLHttpRequest is controlled by the withCredentials attribute.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值