如何正确读取编码后的GET参数?含JS编码重定向场景
首先咱们得搞明白为啥会出现参数截断的情况:
当你用encodeURIComponent把用户输入编码后放到URL路径里(比如/search/[编码内容]),服务器处理请求时通常会自动对URL路径部分做URL解码。这就导致原本编码后的%26变回了&,而&在HTTP查询字符串里是参数分隔符——PHP看到这个&,就会把它后面的内容当成新的GET参数,自然你的$_GET['parameters']就只能拿到&之前的部分了。
比如你的例子里,编码后的URL是example.com/search/What%20is%20the%20meaning%20of%20%26this%20sign%3F,服务器解码后传递给PHP的参数就变成了parameters=What is the meaning of &this sign?,PHP会把parameters解析为"What is the meaning of ",同时多出来一个this参数,值是" sign?",这就是内容不完整的根源。
下面给你两种靠谱的解决办法:
方法1:直接从请求URI提取原始路径部分
绕过$_GET的自动解析,直接获取完整请求URI,手动提取并解码需要的内容。PHP里可以用$_SERVER['REQUEST_URI']拿到完整请求路径:
// 获取完整的请求URI $requestUri = $_SERVER['REQUEST_URI']; // 提取/search/后面的部分(注意要和你的URL结构匹配) $encodedQuery = substr($requestUri, strlen('/search/')); // 解码得到原始用户输入 $originalQuery = urldecode($encodedQuery); // 现在$originalQuery就是完整内容了 echo $originalQuery; // 输出:What is the meaning of &this sign?
这种方法最直接,不需要依赖服务器重写规则配置,兼容性也更好。
方法2:修正服务器重写规则(如果用了URL重写)
如果你是通过mod_rewrite(Apache)或Nginx的rewrite规则把/search/xxx映射到index.php?parameters=xxx,那要确保规则不会提前解码或破坏编码后的字符。
Apache示例(mod_rewrite)
在.htaccess里添加[NE](No Escape)标志,告诉服务器不要对捕获到的路径部分转义:
RewriteEngine On RewriteRule ^search/(.*)$ index.php?parameters=$1 [L,NE]
添加NE后,服务器会把编码后的%26原封不动传给PHP,这时候你用urldecode($_GET['parameters'])就能得到完整的原始输入。
Nginx示例
在Nginx配置里确保rewrite时保留原始编码:
location /search { rewrite ^/search/(.*)$ /index.php?parameters=$1 break; }
Nginx默认不会对rewrite后的参数做额外编码,这样配置后,PHP里的$_GET['parameters']就是完整的编码字符串,解码后即可使用。
额外提醒:改用查询参数传递更省心
其实如果把编码后的内容放到查询参数里(比如/search?query=[编码内容]),操作会更简单:
window.location.href = "/search?query=" + encodeURIComponent(query);
这时候PHP里直接用$_GET['query']就能拿到完整的编码内容,因为encodeURIComponent已经把&转成了%26,服务器会正确识别这是query参数的一部分,不会当作分隔符。这种方式不需要处理路径解析的问题,更省心。
内容的提问来源于stack exchange,提问作者Heriberto Juarez

