jQuery POST请求后丢失了PHP Session数据

3
我知道这个问题似乎经常被问到,但请继续阅读。问题是,正如标题所示,当我向另一个页面发出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);
    }
);

Script B

<?
session_start();

$msg = session_id()."\n";
$msg .= print_r($_SESSION,true);
exit($msg);
?>

这是我的调试方式。脚本B显示了相同的会话ID,但没有会话变量。
我已经疯狂地想办法解决这个问题了。另一件让我感到困扰的事情是,服务器上的另一个文件夹中完全相同的脚本可以正常工作。
请帮帮我... 我已经没有更多的想法了。
更新:更多调试信息
我通过终端中的“tail -f”查看了PHP创建的'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.'。
大量调试..发现了奇怪的事情
我比较了其他系统中使用相同登录脚本的会话处理程序是如何编写'sess'文件的。在其他系统中,“Script A”和“Script B”都会将加密信息写入文件。问题在于,在这个特定的系统中,“Script A”没有以任何方式编写文件,但是“Script B”是这样的。
我怀疑“Script B”期望会话信息已经加密,因此因为它没有能够读取变量,它们就消失了。当尝试从“Script B”保持变量活动到“Script A”时,情况也是一样的。
所以现在我的问题是,即使我没有告诉它们如何做到这一点,为什么“Script A”和“Script B”正在使用不同的session_write处理程序?我如何强制它们使用相同的处理程序?

我们需要脚本checkOTP.php的代码来进行检查。 - Mihai Zinculescu
这是脚本B。我将编辑问题。 - Alvaro Flaño Larrondo
尝试使用echo来调试,而不是使用exit,因为后者可能会导致您的会话过早关闭。我曾经因为在代码中的die()语句干扰了会话的持久化而疯狂地调试过很多次。 - rdiz
它没有改变结果。 - Alvaro Flaño Larrondo
5个回答

11

我终于搞定了。

就像我在问题中发布的那样,问题在于session_handler使用了不同的编码方式来写入sess文件。所以两个脚本都试图读取该文件,但它们都无法正确读取变量。

我有一个php.ini文件,使用指令改变默认字符集。

default_charset = "iso-8859-1"

由于服务器管理员进行了一些更改,我不得不使用这个指令。我在根目录中创建了一个名为.user.ini的文件来使用ISO编码,但我忘记删除这个php.ini文件。

可能是由于php.ini文件只影响其中一个脚本(另一个脚本位于不同的文件夹中),导致字符集干扰了编码/解码过程。因此,我删除了该指令,问题消失了。

希望这个问题将有助于将来的某个人。


0
尝试设置会话时间:
define("SESSION_TIME_EXPIRED",'172800');    
session_set_cookie_params(SESSION_TIME_EXPIRED); 
session_name('user');
session_start();

0

我曾经遇到过同样的问题。 我正在使用自定义会话。 使用这个

session_regenerate_id();

不是

session_regenerate_id(true);

在开始会话后立即使用此功能


0

您的会话未被写入磁盘或其他存储设备,因为在进行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
)

我想我试过那样做了。明天我会再试一次,然后告诉你结果如何。 - Alvaro Flaño Larrondo
它没有起作用。我怀疑服务器配置有问题。 - Alvaro Flaño Larrondo
也许这是一个权限问题,请检查运行Web服务器的用户是否有权限将文件写入session.save_path。此外,您可以在脚本执行时检查会话文件是否在会话保存路径中创建。 - Ugur
所有文件权限都正常。文件正在被写入/读取,问题(如我更新的问题)是该文件在每个脚本中以不同的方式进行编码。 - Alvaro Flaño Larrondo

0

实际上,值为0的会话将持续到浏览器关闭。http://php.net/manual/en/session.configuration.php#ini.session.cookie-lifetime - Alvaro Flaño Larrondo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接