[PHP cURL]:Session cookie 未保存?
[PHP cURL]: Session cookies not saved?
我正在扩展一个 php 脚本,它检查是否启用 javascript 以在第二次后停止重新加载(当 js 似乎被关闭时)。 Here is a link to the original php script by erm3nda。从他的代码片段中可以看出,第一次加载页面时,脚本(进一步 'caller')打印一个带有 jquery ajax 请求的脚本标签到同一页面,但带有$_GET
header,它被在后台加载的同一页面捕获(此外 'called script')并将 $_SESSION
变量设置为 1。被调用的脚本完成其工作后在后台,调用者重新加载(并再次回显此 ajax 查询)直到它能够找到要设置为 1 的 same-named $_SESSION
变量。如果没有,它会在使用 "javascript is disabled" 重新加载进程,如果它被设置为 1,它将以 "javascript is enabled" 退出。我开始修改此代码以在页面重新加载一次后停止重新加载页面。因此我目前正在使用这个脚本:
test.php
<html><body><?php
header('Content-Type: text/html; charset=utf-8');
ini_set('display_errors', 1);
ini_set('log_errors',1);
ini_set('display_startup_errors', 1);
ini_set('error_reporting', E_ALL);
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
function start_session() {
if(version_compare(phpversion(), "5.4.0") != -1){
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
} else {
if(session_id() == '') {
session_start();
}
}
}
start_session();
if (!isset($_SESSION['js']) && !isset($_REQUEST['sessionstart']) && !isset($_REQUEST['setjsoff']) && !isset($_SESSION['jsoff'])) {
echo '<script src="./js/jquery.js"></script><script type="text/javascript">$(document).ready(function(){$.get(document.URL.substring() + "?sessionstart=1");});</script>';
}
if (isset($_REQUEST['sessionstart'])) {
$_SESSION['js'] = 1;
exit("in sessionstart mode");
} else {
if (isset($_REQUEST['setjsoff'])) {
$_SESSION['jsoff'] = 1;
if ($_SESSION['jsoff'] == 1) {
exit("in setjsoff mode (success)");
} else {
exit("jsoff unsuccessful");
}
} else {
session_destroy();
}
}
if (!isset($_SESSION['js'])) {
if (!isset($_SESSION['jsoff'])) {
if (!isset($_REQUEST['sessionstart'])) {
$ch = curl_init();
$username = "***";
$password = "***";
curl_setopt($ch, CURLOPT_URL, "***/test.php?setjsoff=1");
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
curl_setopt($ch, CURLOPT_HTTPGET, true);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$chout = curl_exec($ch);
curl_close($ch);
echo "curl init - ".$chout." - ";
}
header("Refresh: 1");
exit("301 Redirect");
}
echo "Javascript is not enabled";
} else {
echo "Javascript is enabled";
}
?></body></html>
(敏感信息被替换为***
)
在启用 javascript 的情况下,该脚本目前可以正常运行:加载、重新加载一次并且调用者输出 "javascript is enabled".
如果不启用 javascript,调用者会加载、重新加载并在重新加载时回显此信息(有意):“curl init - HTTP/1.1 200 OK Date: *** GMT Server: Apache X-Powered-By: PHP/5.6.36 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Set-Cookie: PHPSESSID=***; path=/ Transfer-Encoding: chunked Content-Type: text/html; charset=utf-8 in setjsoff mode (success) - 301 Redirect
”。
(敏感信息被替换为***
)
如您所见,输出分为 3 部分:
- curl init
表示 curl 已启动(不输出错误)
- the header information of the called page via curl + output of that page
- 301 redirect
表示页面已完全执行并即将重新加载
header 是收到的最重要的消息,因为它主要揭示了后台发生的事情。似乎 curl 调用了页面,页面 returns in setjsoff mode (success)
(这意味着它将 $_SESSION['js']
设置为 1)和很多我无法解释的 header 信息。
这里(最后)是我的问题:之后页面继续重新加载(所以 session 变量不知何故丢失了?)。 header 信息是否显示出任何问题,或者我是否忘记通过 curl_setopt
设置基本选项?
基本问题是您不是实际重新加载页面。您可能导致 服务器 浏览到同一页面,但这是与触发它的原始客户端会话完全不同的会话。此外,您没有为 curl 指定 cookie jar,因此即使您可以设法从中恢复,您的会话和来自服务器调用的关联 cookie 也会丢失。
然而,第一项是根本问题:您正在尝试做一些您甚至不应该考虑的事情。幸运的是,HTML 规范为您提供了一个可以使用的 <noscript>
元素。
所以简单地发出这样的东西:
<script type="text/javascript">/*<![CDATA[*/
/* JS code goes here */
/*]]>*/</script>
<noscript>
<!--
- hit a PHP endpoint that returns a static resource you can hide
- that PHP script can adjust the session as necessary.
-->
<img src="/dummy/image/script.php?jsoff=1"
style="width:0px!important;height:0px!important;">
</noscript>
更好的是:为什么不简单地假设没有 JavaScript 可用,而是在命中单独的 PHP 脚本时重新考虑这一点?然后你可以在页面的 <head>
中简单地 link 静态 <script>
资源......一个更简单和更强大的解决方案。
我正在扩展一个 php 脚本,它检查是否启用 javascript 以在第二次后停止重新加载(当 js 似乎被关闭时)。 Here is a link to the original php script by erm3nda。从他的代码片段中可以看出,第一次加载页面时,脚本(进一步 'caller')打印一个带有 jquery ajax 请求的脚本标签到同一页面,但带有$_GET
header,它被在后台加载的同一页面捕获(此外 'called script')并将 $_SESSION
变量设置为 1。被调用的脚本完成其工作后在后台,调用者重新加载(并再次回显此 ajax 查询)直到它能够找到要设置为 1 的 same-named $_SESSION
变量。如果没有,它会在使用 "javascript is disabled" 重新加载进程,如果它被设置为 1,它将以 "javascript is enabled" 退出。我开始修改此代码以在页面重新加载一次后停止重新加载页面。因此我目前正在使用这个脚本:
test.php
<html><body><?php
header('Content-Type: text/html; charset=utf-8');
ini_set('display_errors', 1);
ini_set('log_errors',1);
ini_set('display_startup_errors', 1);
ini_set('error_reporting', E_ALL);
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
function start_session() {
if(version_compare(phpversion(), "5.4.0") != -1){
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
} else {
if(session_id() == '') {
session_start();
}
}
}
start_session();
if (!isset($_SESSION['js']) && !isset($_REQUEST['sessionstart']) && !isset($_REQUEST['setjsoff']) && !isset($_SESSION['jsoff'])) {
echo '<script src="./js/jquery.js"></script><script type="text/javascript">$(document).ready(function(){$.get(document.URL.substring() + "?sessionstart=1");});</script>';
}
if (isset($_REQUEST['sessionstart'])) {
$_SESSION['js'] = 1;
exit("in sessionstart mode");
} else {
if (isset($_REQUEST['setjsoff'])) {
$_SESSION['jsoff'] = 1;
if ($_SESSION['jsoff'] == 1) {
exit("in setjsoff mode (success)");
} else {
exit("jsoff unsuccessful");
}
} else {
session_destroy();
}
}
if (!isset($_SESSION['js'])) {
if (!isset($_SESSION['jsoff'])) {
if (!isset($_REQUEST['sessionstart'])) {
$ch = curl_init();
$username = "***";
$password = "***";
curl_setopt($ch, CURLOPT_URL, "***/test.php?setjsoff=1");
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
curl_setopt($ch, CURLOPT_HTTPGET, true);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$chout = curl_exec($ch);
curl_close($ch);
echo "curl init - ".$chout." - ";
}
header("Refresh: 1");
exit("301 Redirect");
}
echo "Javascript is not enabled";
} else {
echo "Javascript is enabled";
}
?></body></html>
(敏感信息被替换为***
)
在启用 javascript 的情况下,该脚本目前可以正常运行:加载、重新加载一次并且调用者输出 "javascript is enabled".
如果不启用 javascript,调用者会加载、重新加载并在重新加载时回显此信息(有意):“curl init - HTTP/1.1 200 OK Date: *** GMT Server: Apache X-Powered-By: PHP/5.6.36 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Set-Cookie: PHPSESSID=***; path=/ Transfer-Encoding: chunked Content-Type: text/html; charset=utf-8 in setjsoff mode (success) - 301 Redirect
”。
(敏感信息被替换为***
)
如您所见,输出分为 3 部分:
- curl init
表示 curl 已启动(不输出错误)
- the header information of the called page via curl + output of that page
- 301 redirect
表示页面已完全执行并即将重新加载
header 是收到的最重要的消息,因为它主要揭示了后台发生的事情。似乎 curl 调用了页面,页面 returns in setjsoff mode (success)
(这意味着它将 $_SESSION['js']
设置为 1)和很多我无法解释的 header 信息。
这里(最后)是我的问题:之后页面继续重新加载(所以 session 变量不知何故丢失了?)。 header 信息是否显示出任何问题,或者我是否忘记通过 curl_setopt
设置基本选项?
基本问题是您不是实际重新加载页面。您可能导致 服务器 浏览到同一页面,但这是与触发它的原始客户端会话完全不同的会话。此外,您没有为 curl 指定 cookie jar,因此即使您可以设法从中恢复,您的会话和来自服务器调用的关联 cookie 也会丢失。
然而,第一项是根本问题:您正在尝试做一些您甚至不应该考虑的事情。幸运的是,HTML 规范为您提供了一个可以使用的 <noscript>
元素。
所以简单地发出这样的东西:
<script type="text/javascript">/*<![CDATA[*/
/* JS code goes here */
/*]]>*/</script>
<noscript>
<!--
- hit a PHP endpoint that returns a static resource you can hide
- that PHP script can adjust the session as necessary.
-->
<img src="/dummy/image/script.php?jsoff=1"
style="width:0px!important;height:0px!important;">
</noscript>
更好的是:为什么不简单地假设没有 JavaScript 可用,而是在命中单独的 PHP 脚本时重新考虑这一点?然后你可以在页面的 <head>
中简单地 link 静态 <script>
资源......一个更简单和更强大的解决方案。