`ajax`跨域时`session`丢失了!!!

Posted Monkey聊架构

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了`ajax`跨域时`session`丢失了!!!相关的知识,希望对你有一定的参考价值。


前几天公司同事前后端分离开发,登录时传递session数据时(不懂为啥不用token),出现了一个挺棘手的错误:

  • ajax跨域时session丢失了!!!

解决方法:

  1. 首先我Google了一下这个问题的原因,我找到了这个:

(1)Access-Control-Allow-Origin
该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。
(2)Access-Control-Allow-Credentials
该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。
(3)Access-Control-Expose-Headers
该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。上面的例子指定,getResponseHeader('FooBar')可以返回FooBar字段的值。
3.2 withCredentials 属性
上面说到,CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow-Credentials字段。
Access-Control-Allow-Credentials: true
------  阮一峰的网络日志

查看原文

  1. 我写了一个demo来试验这个方法:

  • 前端代码

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Title</title>
   <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script></head>
<body>
name: <input type="text" name="inputTest" value=""><br>
password: <input type="password" name="pwd" id="pwd" value=""><br>
<button id="but">提交</button>
</body>
<script>
   $("button").click(function () {
       var names=$("input[name='inputTest']").val();
       var pwds=$("input[name='pwd']").val();
       var url = 'http://example.com/demo/test.php';
       var postData = {'name':names, 'pwd':pwds};
       $.ajax({
           type: "POST",
           url: url,
           data:postData,
           dataType: 'jsonp',
           jsonp:'callback',
           xhrFields: {
               withCredentials: true
           },
           crossDomain: true,
           success:function(res){
               console.log(res.name)
           },
           error:function(){}
       })
   });
</script>
</html>
  • 后端php代码:(test.php)

<?php
//简单测试上述方法
header("Access-Control-Allow-Creadentials: true");
header("Access-Control-Allow-Origin: http://shili.com");
$name = $_REQUEST['name'];
$pwd = $_REQUEST['pwd'];
session_start();
$_SESSION['name'] = $name;
$data = ['name' => $_SESSION['name'], 'pwd' => $pwd];
$res = json_encode($data);
$callback = $_GET['callback'];
echo $callback . "($res)";
?>

这里需要注意的是:

需要注意的是,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。

ceshi.php

<?php
session_start();
$name = $_SESSION['name'];
var_dump($name);
?>

测试结束,可以正确的打印sessionname的值。

最后希望小伙伴可以多看一些优秀的文章作品:
比如:

[阮一峰的个人网站] http://www.ruanyifeng.com/home.html


以上是关于`ajax`跨域时`session`丢失了!!!的主要内容,如果未能解决你的问题,请参考以下文章

跨域时session丢失问题的解决

当跨域时,js ajax 请求出现options请求

jquery ajax 跨域问题

HTTP跨域时为何要发送options请求

ajax跨域请求的处理

解决vue nodejs中cros跨域cookie和session失效的问题