urlencoded正斜杠正在破坏URL
关于系统
我在我的项目中有这种格式的URL: –
http://project_name/browse_by_exam/type/tutor_search/keyword/class/new_search/1/search_exam/0/search_subject/0
关键字/类别对意味着使用“class”关键字进行search。
我有一个共同的index.php文件,它执行项目中的每个模块。 只有一个重写规则,从URL中删除index.php: –
RewriteCond $1 !^(index\.php|resources|robots\.txt) RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php [L,QSA]
我正在使用urlencode(),同时准备searchURL和urldecode(),同时阅读searchURL。
问题
只有正斜杠字符正在破坏导致404页未find错误的URL。 例如,如果我searchone/two
URL是
http://project_name/browse_by_exam/type/tutor_search/keyword/one%2Ftwo/new_search/1/search_exam/0/search_subject/0/page_sort/
我该如何解决? 我需要保持index.php隐藏在URL中。 否则,如果不需要的话,就不会有正斜杠的问题,我可以使用这个URL:
http://project_name/index.php?browse_by_exam/type/tutor_search/keyword/one %2Ftwo/new_search/1/search_exam/0/search_subject/0
由于安全原因,Apache拒绝所有具有%2F
URL:出于安全原因:脚本通常不能(即不重写)区分%2F
和/
由于PATH_INFO
环境variables被自动URL解码(这是愚蠢的,但是CGI规范的一个长期的部分,所以没有什么可以做的)。
您可以使用AllowEncodedSlashes
指令closures此function,但请注意,其他Web服务器仍将禁止它(不能selectclosures此function),而其他字符也可能是禁忌(例如%5C
),而%00
特别是将永远被Apache和IIS阻止。 因此,如果您的应用程序依赖于能够在path部分中使用%2F
或其他字符,则会限制您的兼容性/部署选项。
我正在使用urlencode()准备search的URL
您应该使用rawurlencode()
,而不是urlencode()
来转义path部分。 urlencode()
被错误地命名,它实际上是application/x-www-form-urlencoded
数据,例如在查询string或POST请求的主体中,而不是URL的其他部分。
区别在于+
不代表path部分的空间。 rawurlencode()
将正确地生成%20
,它将在表单编码数据和URL的其他部分都能正常工作。
在Apache中,AllowEncodedSlashes On会阻止请求被404立即拒绝。
只是另一个想法如何解决这个问题。
我有同样的问题在URL获取参数斜杠,在我的情况下下面的PHP代码作品:
$value = "hello/world" $value = str_replace('/', '/', $value;?> $value = urlencode($value);?> # $value is now hello%26%2347%3Bworld
我首先用html实体replace斜杠,然后我做了url编码。
URL编码后,用%252Freplace%2F
PHP
function custom_http_build_query($query=array()){ return str_replace('%2F','%252F', http_build_query($query)); }
通过htaccess处理请求
的.htaccess
RewriteCond %{REQUEST_URI} ^(.*?)(%252F)(.*?)$ [NC] RewriteRule . %1/%3 [R=301,L,NE]
资源
$encoded_url = str_replace('%2F', '/', urlencode($url));
在我的托pipe帐户上,这个问题是由于自动为所有帐户设置的ModSecurity规则造成的。 在我报告这个问题时,他们的pipe理员很快删除了我的帐户的这个规则。
这个问题的一个标准解决scheme是通过使可能包含的参数斜杠URL中的最后一个参数允许斜杠。
对于产品代码url,您将有…
mysite.com/product/details/PR12345/22
对于一个search字词,你会有
http://project/search_exam/0/search_subject/0/keyword/Psychology/Management
(这里的关键词是心理学/pipe理)
处理第一个“命名”参数并不是一个大量的工作,然后连接其余的产品代码或关键字。
有些框架内置了这个工具,用于路由定义。
这不适用于包含两个斜杠参数的用例。
使用不同的字符并replace斜杠服务器端
例如Drupal.org使用%21(excalamation mark character!)来表示url参数中的斜杠。
下面的两个链接都起作用:
https://api.drupal.org/api/drupal/includes%21common.inc/7
https://api.drupal.org/api/drupal/includes!common.inc/7
如果您担心该字符可能与参数中的某个字符冲突,请使用字符组合。
所以你的url是http:// project_name / browse_by_exam / type / tutor_search / keyword / one_-!two / new_search / 1 / search_exam / 0 / search_subject / 0
使用js将其更改为斜杠服务器端。
很简单,我使用base64_encode
$term = base64_encode($term) $url = $youurl.'?term='.$term
在你解码这个术语之后
$term = base64_decode($['GET']['term'])
这样编码“/”和“\”
我使用JavaScript的encodeURI()函数的URL部分,应该被视为字符而不是http地址的正斜杠。 例如:
"/api/activites/" + encodeURI("?categorie=assemblage&nom=Manipulation/Finition")
我通过使用2个自定义函数解决了这个问题:
function slash_replace($query){ return str_replace('/','_', $query); } function slash_unreplace($query){ return str_replace('_','/', $query); }
所以编码我可以打电话:
rawurlencode(slash_replace($param))
并解码我可以打电话
slash_unreplace(rawurldecode($param);
干杯!
如果以这种方式使用,可以使用%2F
:
?param1=value1¶m2=value%2Fvalue
但是如果你使用/param1=value1/param2=value%2Fvalue
它会抛出一个错误。