jQuery POST 请求后 PHP 会话数据丢失
Posted
技术标签:
【中文标题】jQuery POST 请求后 PHP 会话数据丢失【英文标题】:PHP Session data lost after jQuery POST request 【发布时间】:2015-08-20 23:11:44 【问题描述】:我知道这个问题似乎和它被问过很多次一样,但请继续阅读。
问题是,正如标题所暗示的,当我向另一个页面发出 POST 请求时,会话数据没有保存在我的 php 脚本中。
是的,所有脚本的第一行都有session_start();
。
是的,我检查了 session_id 是否相同,确实如此。
apache 日志没有显示任何错误(我有它显示所有
错误)
我测试了会话是否可以创建用于创建/读取会话变量的简单页面,并且可以正常工作。当我使用 POST 请求时,它的行为很奇怪。
两个脚本都在同一个服务器上。
我将展示我编辑的代码,只是为了展示它的作用。
脚本 A
<?
session_start();
echo session_id()."<br>";
print_r($_SESSION);
require_once __DIR__ . '/include/config.php';
ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 1);
session_set_cookie_params(
0,
ini_get('session.cookie_path'),
ini_get('session.cookie_domain'),
isset($_SERVER['HTTPS']),
true
);
$_SESSION['haygsdb18'] = true;
$_SESSION['user_name'] = '';
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
$_SESSION['REMOTE_ADDR'] = md5($_SERVER['REMOTE_ADDR']);
$include_path = str_replace($_SERVER['DOCUMENT_ROOT'],'',__DIR__);
?>
$.post(
"<?=$include_path?>/include/ScriptB.php",
OTP: OTP,
function(data)
alert(data);
);
脚本 B
<?
session_start();
$msg = session_id()."\n";
$msg .= print_r($_SESSION,true);
exit($msg);
?>
这样我正在调试。脚本 B 显示相同的会话 id,但没有会话变量。
我想弄清楚它已经失去了理智。让我感到害怕的另一件事是服务器中另一个文件夹中的相同脚本(完全相同,复制粘贴)运行良好。
请帮忙...我的想法已经用完了。
更新:更多调试信息
我查看了由 php 在终端中使用 tail -f
创建的 sess
文件。加载脚本 A 时,变量被写入文件中,并且当进行 AJAX 调用时,文件被清空(不删除,只是清空)。
当脚本A执行$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
时,sess文件被写入HTTP_USER_AGENT|s:32:"2589a220583546006658f54ada687b45";
,但是当脚本B执行$_SESSION['TEST'] = '1';
时,sess文件中的所有内容被替换为C1Hw6hhbpX-jWhvbRfz_reKX4tT66bcNpYGLGzxEg7I.
大量调试.. 发现了一个奇怪的东西
我比较了 session_handler 如何在我使用相同登录脚本的其他系统中编写 sess 文件。在其他系统中,脚本 A 和脚本 B 将加密信息写入文件。问题是在这个特定系统中,脚本 A 没有使用任何加密写入文件,但脚本 B 是。
我怀疑脚本 B 期望会话信息被加密,所以因为它不是它无法读取变量并且它们已经消失了。当试图保持从脚本 B 到脚本 A 的变量时,也会发生同样的情况。
所以现在我的问题是,脚本 A 和脚本 B 怎么可能在我没有告诉他们这样做的情况下使用不同的 session_write 处理程序?我如何强迫他们使用相同的?
【问题讨论】:
我们需要脚本checkOTP.php的代码来检查.. 这是脚本 B.. 我将编辑问题 尝试,而不是使用退出,这可能会导致您的会话过早关闭,只是为了回显您正在调试的任何内容。我在调试东西时被逼疯了太多次,代码中某处的die()
语句干扰了会话的持续。
它没有改变结果。
【参考方案1】:
您的会话未写入磁盘或您正在使用的任何存储,因为在您进行 ajax 调用时脚本执行可能未完成。
您可以使用 session_write_close() 函数将会话数据保存到存储中(很可能是您的 /tmp/ 文件夹) http://php.net/manual/tr/function.session-write-close.php
<?php
session_start();
echo session_id()."<br>";
print_r($_SESSION);
ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 1);
session_set_cookie_params(0,ini_get('session.cookie_path'),ini_get('session.cookie_domain'),isset($_SERVER['HTTPS']),true);
$_SESSION['haygsdb18'] = true;
$_SESSION['user_name'] = '';
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
$_SESSION['REMOTE_ADDR'] = md5($_SERVER['REMOTE_ADDR']);
//write the session before the script execution ends
session_write_close();
$include_path = str_replace($_SERVER['DOCUMENT_ROOT'],'',__DIR__);
?>
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
$(document).ready(function()
$.post("scriptB.php", OTP: "OTP", function(data)
alert(data););
);
</script>
</head>
<body>
</body>
</html>
这是我的输出;
tdiiqame0i4ldshc8m20n8d9o6
Array
(
[haygsdb18] => 1
[user_name] =>
[HTTP_USER_AGENT] => bc9d9d38aa0626db612842a1e0d09ea9
[REMOTE_ADDR] => f528764d624db129b32c21fbca0cb8d6
)
【讨论】:
我想我尝试过这样做。我明天再试一次,告诉你结果如何。 它没有用。我怀疑服务器配置有问题。 php.net/manual/en/session.configuration.php 可能是权限问题,请检查您的运行网络服务器的用户是否有权将文件写入 session.save_path。您还可以检查脚本执行时是否在会话保存路径中创建会话文件。 所有文件权限都OK。正在写入/读取文件,问题(当我更新问题时)是文件在每个脚本中以不同的方式编码。【参考方案2】:我终于明白了。
正如我在问题中发布的那样,问题在于 session_handler 正在使用不同的编码编写 sess 文件。因此,这两个脚本都试图读取文件,但都无法正确读取变量。
我有一个 php.ini
文件,用于通过指令更改默认字符集
default_charset = "iso-8859-1"
我不得不使用这个指令,因为服务器管理员做了一些更改。我在根目录下创建了一个.user.ini
文件来使用ISO 编码,但是我忘记删除这个php.ini
文件了。
可能由于php.ini
文件只影响了其中一个脚本(另一个位于不同的文件夹中),字符集与编码/解码过程发生了冲突。所以我删除了那个指令,问题就消失了。
希望这个问题将来能对某人有所帮助。
【讨论】:
【参考方案3】:尝试设置会话时间:
define("SESSION_TIME_EXPIRED",'172800');
session_set_cookie_params(SESSION_TIME_EXPIRED);
session_name('user');
session_start();
【讨论】:
【参考方案4】:session_set_cookie_params(0, ...)
不创建立即过期的会话吗?
http://php.net/manual/en/function.session-set-cookie-params.php
【讨论】:
实际上值 0 会创建一个持续到浏览器关闭的会话。 php.net/manual/en/…【参考方案5】:我遇到了同样的问题。 我正在使用自定义会话。 用这个
session_regenerate_id();
不是
session_regenerate_id(true);
在开始会话后使用它
【讨论】:
以上是关于jQuery POST 请求后 PHP 会话数据丢失的主要内容,如果未能解决你的问题,请参考以下文章