test.php
文件的代码如下:
<code> <!--情况1--> <script type="text/javascript"> //var a = "<?php echo $_GET['input'];?>"; </script> <!--情况2--> <script type="text/javascript"> //var a = "start_%0a_end"; </script> </code>
情况1:
变量a的值是可控的,由参数input决定,
所以,当从浏览器访问:http://127.0.0.1/test.php?input=start_%0a_end
的时候
查看网页源代码,结果如下:
<code>//省略…… <!--情况1--> <script type="text/javascript"> //var a = start_ _end; </script> <!--情况2--> <script type="text/javascript"> //var a = "start_%0a_end"; </script> //省略…… </code>
我们可以发现,情况1中,出现了换行,而情况2保持原样。
为什么会出现这种情况呢?
谁能帮忙详细讲解下其中的原理吗?
说下我对此问题的看法:
当客户端访问网址(http://127.0.0.1/test.php?input=start_%0a_end)的时候,由于是php文件,所以服务端会交个Apache服务器解析执行,并把结果返回给服务端,服务端再将结果通过http响应返回给客户端(浏览器),浏览器再将页面渲染出来,呈现给用户。
用户--->浏览器--->服务器--->apache
那么,
换行到底是:
1.出现在Apache的解析执行的阶段
2.还是浏览器将最终结果呈现给用户这一阶段
如果是出现在Apache的解析执行阶段,那么<?php echo "start_%0a_end";?>
应该也会出现换行,但实际上并没有
而如果换行是出现在:浏览器的渲染阶段,那么
<code><br><br><script type="text/javascript"> var a = "start_%0a_end";//注意:此行没有注释 </script> </code>
应该也会出现换行才是,但实际上也没有
回复内容:
test.php
文件的代码如下:
<code> <!--情况1--> <script type="text/javascript"> //var a = "<?php echo $_GET['input'];?>"; </script> <!--情况2--> <script type="text/javascript"> //var a = "start_%0a_end"; </script> </code>
情况1:
变量a的值是可控的,由参数input决定,
所以,当从浏览器访问:http://127.0.0.1/test.php?input=start_%0a_end
的时候
查看网页源代码,结果如下:
<code>//省略…… <!--情况1--> <script type="text/javascript"> //var a = start_ _end; </script> <!--情况2--> <script type="text/javascript"> //var a = "start_%0a_end"; </script> //省略…… </code>
我们可以发现,情况1中,出现了换行,而情况2保持原样。
为什么会出现这种情况呢?
谁能帮忙详细讲解下其中的原理吗?
说下我对此问题的看法:
当客户端访问网址(http://127.0.0.1/test.php?input=start_%0a_end)的时候,由于是php文件,所以服务端会交个Apache服务器解析执行,并把结果返回给服务端,服务端再将结果通过http响应返回给客户端(浏览器),浏览器再将页面渲染出来,呈现给用户。
用户--->浏览器--->服务器--->apache
那么,
换行到底是:
1.出现在Apache的解析执行的阶段
2.还是浏览器将最终结果呈现给用户这一阶段
如果是出现在Apache的解析执行阶段,那么<?php echo "start_%0a_end";?>
应该也会出现换行,但实际上并没有
而如果换行是出现在:浏览器的渲染阶段,那么
<code><br><br><script type="text/javascript"> var a = "start_%0a_end";//注意:此行没有注释 </script> </code>
应该也会出现换行才是,但实际上也没有
接 @安坚实
的答案,query string
由于地址栏显示、日志记录、或者转义等各方面的需要,必须将部分字符进行翻译(比如无法显示的字符、有特殊含义的控制字符等)
所以你在百度搜索一个
&
符号的时候 访问到的链接 实际是http://www.baidu.com/s?wd=%26
因为这个字符与query string中的参数连接符
冲突了,需要进行转义
这个过程就是一个编码的过程,这样的编码算法最常见的就是 URLEncode
和 Base64Encode
而此处使用的是 URLEncode
,这个是在 RFC 3986 中定义的
服务端收到了这个请求时,先原样记录在日志中,然后将参数变成应用程序里的字符串 交给web应用处理
这个时候就需要进行一个解码过程,否则得到的数据就与预期不一致了
接上面那个例子,我想搜索的是 字符串
&
而不是 字符串%26
,因此需要解码变回&
再解释LZ的例子,浏览器中访问http://127.0.0.1/test.php?input=start_%0a_end
时,
其实input这个参数的实际值 并不是 start_%0a_end
这个字符串,只是因为地址栏无法显示换行符,将换行符进行了转义, 他的实际值就是start_[换行]_end
,页面输出时,将他还原成了[换行]
如果你想要指定 input参数的实际值为 start_%0a_end
, 需要将%
做一次转义,变为 %25
尝试访问一下 http://127.0.0.1/test.php?input=start_%250a_end
解析过程其实是这样的:
用户 --> 浏览器 --> 服务器 --> apache --> PHP解释器
首先,start_%0a_end
被传递给PHP解释器时,%0a 并没有被转换成换行。
<code>var_dump($_SERVER['QUERY_STRING']); # string(19) "input=start_%0a_end" </code>
但是,当它被写入到 $_GET 全局数组里时,就变成换行了
<code>var_dump($_GET['input']); #string(11) "start_ #_end" </code>
因此,应该是PHP解释器在把 query string 的值写入 $_GET 里时,进行了某些处理
至于为什么进行这样的处理,以及如何解决... 这个超出我的知识范围了...
其实这里只涉及到一个知识点,URIEncode,
URI内的字符在传输时会进行转义,当处理程序收到数据时会进行反转义;%0a
的转义过程大致如下(JS,PHP的过程 @安坚实 已解释了部分):
<code>// encode encodeURIComponent('\n') // %0A encodeURIComponent('\n').toLowerCase() === '%0a' // true // decode decodeURIComponent('%0a').charCodeAt(0) // 10 '\n'.charCodeAt(0) // 10 </code>
关于 JS URI 编码部分可见:
http://www.ruanyifeng.com/blog/2010/02/url_encoding.html

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

方法:1、用“str_replace(" ","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\ \;||\xc2\xa0)/","其他字符",$str)”语句。

查找方法:1、用strpos(),语法“strpos("字符串值","查找子串")+1”;2、用stripos(),语法“strpos("字符串值","查找子串")+1”。因为字符串是从0开始计数的,因此两个函数获取的位置需要进行加1处理。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

Dreamweaver CS6
视觉化网页开发工具

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

WebStorm Mac版
好用的JavaScript开发工具

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。