时间:2021-07-01 10:21:17 帮助过:2人阅读
以下这段代码保存为test.php
'; $_SESSION['test'] = $_SERVER['PATH_INFO']; var_dump($_SESSION['test']); ?>
在本地测试这段代码,访问url http://localhost/test.php/a
$_SERVER['PATH_INFO']的值是'/a',赋值后$_SESSION['test']的值是'/a',页面刷新后,在页面开头输出$_SESSION['test']理论上应该也是'/a',可是$_SESSION['test']变成了'https://www.gxlcms.com/notice'。
其中https://www.gxlcms.com/notice的值同中src的值,src的值改为其他值相应也会输出同样的值
如图:
以下这段代码保存为test.php
'; $_SESSION['test'] = $_SERVER['PATH_INFO']; var_dump($_SESSION['test']); ?>
在本地测试这段代码,访问url http://localhost/test.php/a
$_SERVER['PATH_INFO']的值是'/a',赋值后$_SESSION['test']的值是'/a',页面刷新后,在页面开头输出$_SESSION['test']理论上应该也是'/a',可是$_SESSION['test']变成了'https://www.gxlcms.com/notice'。
其中https://www.gxlcms.com/notice的值同中src的值,src的值改为其他值相应也会输出同样的值
如图:
关键在
浏览器访问的时候加载了/test.php/https://www.gxlcms.com/notice
这时候就触发了test.php,
$_SESSION['test'] = $_SERVER['PATH_INFO']; //此时为https://www.gxlcms.com/notice
所以即使你再刷新, 第一次打印的也是https://www.gxlcms.com/notice
我知道问题所在了,问题就在于你提的这个img
标签里,你的img标签的src填的是https://www.gxlcms.com/notice
。在html中如果你不加任http://xxx
的前缀直接放在这里的话,它会访问当前目录下的此文件,也就是你在刷新这个页面的时候,这个页面又通img
访问了http://localhost/test.php/https://www.gxlcms.com/notice
。
因为浏览器识别的是最后一个斜杠/
,所以认为当前目录是http://localhost/test.php/
。它自动把https://www.gxlcms.com/notice
放在后面构成了此次访问的url。那么访问http://localhost/test.php/https://www.gxlcms.com/notice
当然就会把pathinfo
的https://www.gxlcms.com/notice
设置到session里面啦,所以你每次刷新看到的实际上是img
标签刷新的session。
感谢邀请,前面都回答得很好了。我补充几点:
具体来分析你这段代码:
第一次执行的时候,浏览器先后发起了两次HTTP请求,http://localhost/test.php/a 和 http://localhost/test.php/https://www.gxlcms.com/notice,结果会是这样的:
此时,服务器端session文件内容如下:
对第一个HTTP请求(http://localhost/test.php/a),页面显示“Notice: Undefined index”是因为刚刚session_start()之后没有为$_SESSION['test']赋值就去打印它,必然是不存在这个数组下标的,故报错。
接着,把当前的PATH_INFO(即"/a"存入了session文件中),并输出出来,这就是你在浏览器中肉眼看到的效果了。
由于浏览器遇到了img标签,于是,根据src属性又去请求了http://localhost/test.php/https://www.gxlcms.com/notice(请自行参阅src的相对路径,我就不细说了),这个请求是浏览器在后台进行的,它不会改变当前页面的HTML源码,所以,你看不到页面上有什么变化。
test.php实际又被执行了一遍,对第一个var_dump(),它输出“/a”,接着,它把当前的PATH_INFO(即/https://www.gxlcms.com/notice)赋值给$_SESSION['test'],覆盖了session文件的原值(参见上面的截图),然后再执行第二个var_dump()。这些var_dump()的输出在哪里呢?在“http://localhost/test.php/https://www.gxlcms.com/notice”这个HTTP请求的Response里面,这些文本输出显然不是一个合法的图片,所以你的img标签会显示失败。
两个HTTP请求的证据:
可以看到,两个HTTP请求得到的Reponse Body不一样长的(149 Bytes vs 61 Bytes),因为请求http://localhost/test.php/https://www.gxlcms.com/notice时没有“Notice: Undefined index”报错了。
第二次刷页面的时候,还是两个HTTP请求:
最终你看到的页面如下:
第一个HTTP请求(http://localhost/test.php/a):先打印“/https://www.gxlcms.com/notice”(在session文件里能取出了,参见截图),然后用当前PATH_INFO(“/a”)覆盖之,再打印“/a”。
接着浏览器自动发起第二个HTTP请求(http://localhost/test.php/https://www.gxlcms.com/notice):先在后台打印"/a",再赋值“/https://www.gxlcms.com/notice”,再打印"/https://www.gxlcms.com/notice",由于不是合法的图片内容显示失败,你在页面上也看不到变化。
第3至N次跟第二次刷新页面的过程完全一样。
最后:
建议你加调试技能,刷新页面的时候多看HTTP通信的文本内容,多看session文件内容。
感谢邀请,null、joyqi已经把问题解释清楚了。
顺便提醒一下,第一次var_dump($_SESSION['test']);时,会触发https://www.gxlcms.com/notice,建议严谨一下例如:
if(isset($_SESSION['test'])){ var_dump($_SESSION['test']); }
另外在用chrome时切换到network功能,会发现有一次 http://127.0.0.1/https://www.gxlcms.com/notice 请求。
nginx默认是不支持$_SERVER['PATH_INFO']的,不能保证这个值一定能取到。
检查下session是否生效,本地COOKIE里是否有PHPSESSIONID
。