Ajax 重置 PHP 会话
Ajax resets PHP session
我知道 所以我提前道歉,但我已经多次检查他的解决方案并且它没有解决我的会话重置问题。
我有一个简单的 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
但无济于事。对于这个问题,我深表歉意,但我实在找不到解决办法。
原因是因为 ajax 请求没有随请求一起发送 session id。这会导致 session_start
生成一个新的。
可能导致浏览器在 ajax 请求期间不发送 session cookie 的可能原因是域名不一致。
不是在ini文件上设置session.cookie_domain,而是在运行时设置如下
session_set_cookie_params(33600, '/', 'localhost.api.mydomain', FALSE, TRUE);
session_start();
为了帮助您调试此问题,请转到 chrome 中开发人员工具的网络选项卡。重新加载页面并检查请求 headers 和响应 headers。检查 jquery 向其发送请求的主机。它可能只是将请求发送到本地主机。并且您可能已将站点配置为接受本地主机和 localhost.api.mydomain.
要进行更多检查,请在您的文件中执行类似
的操作
session_set_cookie_params(33600, '/', 'localhost.api.mydomain', FALSE, TRUE);
session_start();
die($_SERVER['HTTP_HOST']);
这将让您比较 jquery 在 ajax 请求期间使用的请求 url。
这是一个 Access-Control
问题,而不是 ajax
问题。
当您直接从您的浏览器访问 url 时,您是在从您正在访问的域中请求一个(会话)cookie。当您使用 ajax
时,在这种情况下,您正在从您正在访问的域以外的域请求 cookie。
在位于 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 就会按预期运行。
我知道
我有一个简单的 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
但无济于事。对于这个问题,我深表歉意,但我实在找不到解决办法。
原因是因为 ajax 请求没有随请求一起发送 session id。这会导致 session_start
生成一个新的。
可能导致浏览器在 ajax 请求期间不发送 session cookie 的可能原因是域名不一致。
不是在ini文件上设置session.cookie_domain,而是在运行时设置如下
session_set_cookie_params(33600, '/', 'localhost.api.mydomain', FALSE, TRUE);
session_start();
为了帮助您调试此问题,请转到 chrome 中开发人员工具的网络选项卡。重新加载页面并检查请求 headers 和响应 headers。检查 jquery 向其发送请求的主机。它可能只是将请求发送到本地主机。并且您可能已将站点配置为接受本地主机和 localhost.api.mydomain.
要进行更多检查,请在您的文件中执行类似
的操作session_set_cookie_params(33600, '/', 'localhost.api.mydomain', FALSE, TRUE);
session_start();
die($_SERVER['HTTP_HOST']);
这将让您比较 jquery 在 ajax 请求期间使用的请求 url。
这是一个 Access-Control
问题,而不是 ajax
问题。
当您直接从您的浏览器访问 url 时,您是在从您正在访问的域中请求一个(会话)cookie。当您使用 ajax
时,在这种情况下,您正在从您正在访问的域以外的域请求 cookie。
在位于 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 就会按预期运行。