【问题标题】:Ajax resets PHP sessionAjax 重置 PHP 会话
【发布时间】:2018-09-05 23:40:42
【问题描述】:

我知道this question has been asked before,所以我提前道歉,但我已经多次检查了他的解决方案,但它并不能解决我的会话重置问题。

我有一个简单的 php 页面,它输出一个用于调试的会话 id。像这样:

<?php
session_start();
echo session_id();
?>

然后我有一个带有jQuery 的简单HTML 页面,它在该页面上执行ajax 请求并记录输出。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script>
      $.post('http://localhost.api.mydomain/sid', {
        some: 'data'
      }, function(data,status) {
        console.log(data);
      });
    </script>
  </head>
  <body>
    Check your console.
  </body>
</html>

如果我手动访问 url http://localhost.api.mydomain/sid 输出永远不会改变,session_id() 保持不变,正如预期的那样。但是,如果我刷新 ajax 页面,输出的 session_id() 会随着每次刷新而改变。

我尝试在php.ini 文件中设置session.cookie_domain,但无济于事。对于这个问题,我深表歉意,但我根本找不到解决方案。

【问题讨论】:

  • 如果会话 cookie 随 HTTP POST 请求一起提供,请在“网络”选项卡上检查浏览器的调试工具。如果您的请求是跨域的,您的浏览器安全功能可能会删除 cookie。
  • 有没有办法解决这个问题?这是一个 API,所以期望每个用户都更改他们的浏览器设置并不完全理想。

标签: php ajax session session-variables session-cookies


【解决方案1】:

这是Access-Control 问题,而不是ajax 问题。

当您直接从浏览器访问 url 时,您正在从您正在访问的域请求一个(会话)cookie。当您使用ajax 时,在这种情况下,您请求的域不是您正在访问的域。

api.example.com 的 php API 文件上,试试这个。

header('Access-Control-Allow-Origin: example.com');
header('Access-Control-Allow-Credentials: true');

然后在您的ajax 请求文件上,像这样使用xhrFields 参数。

  $.ajax({
    url: 'https://api.example.com',
    xhrFields: { withCredentials: true },
    success: function(data) {
      console.log(data)
    }
  });

现在,只要您从源 example.com 调用请求,cookie 就会按预期运行。

【讨论】:

    【解决方案2】:

    原因是ajax请求没有随请求一起发送会话ID。这会导致session_start 生成一个新的。

    可能导致浏览器在ajax请求期间不发送会话cookie的原因是域名不一致。

    不要在ini文件上设置session.cookie_domain,而是在运行时设置如下

    session_set_cookie_params(33600, '/', 'localhost.api.mydomain', FALSE, TRUE);
    session_start();
    

    为了帮助您调试此问题,请转到 chrome 中开发人员工具上的网络选项卡。重新加载页面并检查请求标头和响应标头。检查 jquery 向其发送请求的主机。它可能只是将请求发送到本地主机。并且您可能已将您的站点配置为同时接受 localhost 和 localhost.api.mydomain。

    要进行更多检查,请在您的文件中执行类似的操作

    session_set_cookie_params(33600, '/', 'localhost.api.mydomain', FALSE, TRUE);
    session_start();
    die($_SERVER['HTTP_HOST']);
    

    这将让您比较 jquery 在 ajax 请求期间使用的请求 url。

    【讨论】:

    • 我已尝试按照您描述的方式将session_set_cookie_params() 放在session_start() 的上方和下方,但都没有解决会话重置问题。还有其他想法吗?谢谢。
    • 网络控制台中请求的主机是localhost.api.mydomain,php中HTTP_HOST的输出是localhost.api.mydomain。感谢您的帮助,我真的希望这可以解决问题,但是您还有其他调试建议吗?
    • 非常感谢任何调试帮助。这发生在 Windows 10 开发机器和 Ubuntu 16.04 生产机器上。
    • 好的,我们可以通过聊天来完成吗?我需要查看 chrome 开发工具的网络部分
    • 我很乐意尽我所能提供帮助。我可以复制这个问题,并且我也使用相同的 ubuntu 16.04。和 Windows 8.1
    猜你喜欢
    • 2015-08-18
    • 2017-04-10
    • 2012-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    相关资源
    最近更新 更多