首页 > 解决方案 > PHP 会话在 POST 请求中出错后终止

问题描述

我在 POST 请求后删除 php 会话时遇到问题。如果我使用 POST 方法提交表单,如果在表单重定向的那个页面上出现错误,然后按 F5 重新加载页面,会话将被删除。

好的,这就是我为重现我的问题所做的工作:

我创建了一个空白的 php 项目(下面的服务器详细信息):

4 页。每个页面都以 session_start();

第 1 页:将一些值存储到会话中:

<?php
session_start();
$_SESSION['foo'] = 'bar';

第2页:简单地输出我的会话内容,看看它是否还在。

<?php
session_start();
echo $_SESSION['foo'];

第 3 页:我使用 post 方法创建了一个简单的表单,该表单发布到第 4 页。

<?php
session_start();
echo '<form method="post" action="page4.php">';
echo '<input type="text" name="whatevs">';
echo '<input type="submit">';
echo '</form>';

在第 4 页,我首先通过简单地对 $_POST 执行 print_r 来测试它。但后来我将其更改为以错误 500 响应:

<?php
session_start();
header('HTTP/1.1 500 Internal Server Error');
exit;

所以,这就是发生的事情:我首先转到第 1 页以在会话中存储一个值。然后我转到第 2 页,只是为了查看我的会话值是否已存储。然后我转到第 3 页并将表单提交到第 4 页。当第 4 页返回状态 200 时,一切正常并按预期工作。但是,当我返回错误 500 时,如代码段所示,然后在错误页面上按 F5 刷新页面时,我的会话就消失了。然后我返回到第 2 页,查看我的会话 $_SESSION['foo'] 是否仍然存在,但不是。它被删除了。事实上,PHPSESSID cookie 包含一个新 ID。

如果我立即执行相同的操作(转到第 1 页存储一个值,然后在第 3 页提交我的表单),它不会删除它。如果我在再次提交之前给它一分钟左右,它会的。

如果我删除错误代码并返回带有一些文本的正常状态 200,这将永远不会发生。只有当我返回错误时。

没有其他 cookie 受到影响。他们都在那里。只有会话 cookie 受到影响。

我注意到的另一件事是,当我第一次进入第 4 页并收到错误 500 时,chrome 的网络窗口显示我提交了我的 PHPSESSID cookie,就像在任何页面上一样。当我在第 4 页进行重大刷新时,看起来我不再提交 PHPSESSID cookie,因此服务器的响应现在包含一个新的 PHPSESSID cookie。

服务器详情:

Windows 10,使用 php 7.3.21 运行 xampp

概括:

有人对此一无所知吗?为什么会这样?为什么只使用 POST?为什么它只在第一次尝试时发生,然后在我重复之前等待一分钟左右才会再次发生?这个场景是我们在网站上遇到的一个问题的非常基本的再现,在这里描述起来太复杂了,所以我将它提炼成这个测试用例。

如果有人知道 PHP 的会话和 POST 请求之间的关系,并且可以对这个问题有所了解,我们将不胜感激!

标签: phpsessioncookies

解决方案


因此,事实证明,这与 cookie 的“相同站点”配置有关。从现在开始,默认情况下它设置为“lax”,而不是“none”,如果您在非 200 响应后刷新页面,它不会发送带有 POST 请求的 cookie。

细节上不是 100%,但事实证明它与 samesite=lax 配置有关。


推荐阅读