关于系统
我的项目中有这种格式的URL: -
http://project_name/browse_by_exam/type/tutor_search/keyword/class/new_search/1/search_exam/0/search_subject/0
其中关键字/类对意味着使用“class”关键字进行搜索。
我有一个常见的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]
我在阅读搜索URL时准备搜索URL和urldecode()时使用urlencode()。
问题
只有正斜杠字符会破坏导致404页面未找到错误的URL。例如,如果我搜索one/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
环境变量被自动URL解码(这是愚蠢的,但是脚本不能正常地(即没有重写)告诉/
和PATH_INFO
之间的区别) CGI规范的一个长期部分,所以没有什么可以做的。
您可以使用AllowEncodedSlashes
指令关闭此功能,但请注意其他Web服务器仍然不允许它(没有选项将其关闭),其他字符也可能是禁忌(例如.%5C
),特别是%00
将永远被Apache和IIS阻止。因此,如果您的应用程序依赖于能够在路径部分中使用%2F
或其他字符,那么您将限制兼容性/部署选项。
我在准备搜索URL时使用urlencode()
你应该使用rawurlencode()
,而不是urlencode()
来逃避路径部分。 urlencode()
名称错误,它实际上是application/x-www-form-urlencoded
数据,例如查询字符串或POST请求的正文,而不是URL的其他部分。
区别在于+
并不意味着路径部分的空间。 rawurlencode()
将正确生成%20
,它将在表单编码数据和URL的其他部分中工作。
这是我的拙见。 !!!!别 !!!!更改服务器上的设置以使参数正常工作。这是一个定时炸弹等待有一天你改变服务器时发生。
我发现的最好方法是将参数转换为base 64编码。所以在我的情况下,我从Angular调用一个php服务并传递一个可能包含任何值的参数。
所以我在客户端的打字稿代码如下所示:
private encodeParameter(parm:string){
if (!parm){
return null;
}
return btoa(parm);
}
并在PHP中检索参数:
$item_name = $request->getAttribute('item_name');
$item_name = base64_decode($item_name);
我使用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
它会抛出一个错误。
在url编码后将%2F替换为%252F
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]
资源
在Apache中,AllowEncodedSlashes On会阻止请求立即被404拒绝。
关于如何解决这个问题的另一个想法。
$encoded_url = str_replace('%2F', '/', urlencode($url));
我在url get param中遇到了与斜杠相同的问题,在我的情况下跟随php代码工作:
$value = "hello/world"
$value = str_replace('/', '/', $value;?>
$value = urlencode($value);?>
# $value is now hello%26%2347%3Bworld
我首先用html实体替换斜杠然后我做url编码。
在我的托管帐户上,此问题是由自动为所有帐户设置的ModSecurity规则引起的。在我报告此问题后,他们的管理员会快速删除我的帐户的此规则。
使用不同的字符并替换斜杠服务器端
例如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
如果您担心该字符可能与参数中的字符发生冲突,请使用字符组合。
用js更改它并将其转换回斜杠服务器端。
此问题的标准解决方案是通过使可能包含斜杠的参数包含url中的最后一个参数来允许斜杠。
对于产品代码网址,您将拥有...
mysite.com/product/details/PR12345/22
对于您有的搜索词
http://project/search_exam/0/search_subject/0/keyword/Psychology/Management
(这里的关键词是心理学/管理学)
处理第一个“命名”参数然后将其余参数连接成产品代码或关键字并不是一项大量的工作。
有些框架在其路由定义中内置了此工具。
这不适用于涉及我包含斜杠的两个参数的用例。
对我来说很简单,使用base64_encode
$term = base64_encode($term)
$url = $youurl.'?term='.$term
解码后的术语
$term = base64_decode($['GET']['term'])
这种方式编码“/”和“\”