urlencoded 正斜杠正在破坏 URL
Posted
技术标签:
【中文标题】urlencoded 正斜杠正在破坏 URL【英文标题】:urlencoded Forward slash is breaking URL 【发布时间】:2011-03-15 04:40:25 【问题描述】:关于系统
我的项目中有这种格式的 URL:-
http://project_name/browse_by_exam/type/tutor_search/keyword/class/new_search/1/search_exam/0/search_subject/0
关键字/类对表示使用“类”关键字进行搜索。
我有一个为项目中的每个模块执行的通用 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 时使用 urlencode(),在读取搜索 URL 时使用 urldecode()。
问题
只有正斜杠字符会破坏 URL,导致 404 页面未找到错误。
例如,如果我搜索 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
【问题讨论】:
我觉得最好有这样的 URL:-http://project_name/browse_by_exam?type/tutor_search/keyword/class %2Fnew/new_search/1/search_exam/0/search_subject/0
这样我就摆脱了由 ¶m1=value1¶m2=value2 约定引起的可读性困难,而且我还可以允许正斜杠(现在在查询字符串部分使用?
)我会避免使用AllowEncodedSlashes,因为Bobince 说Also some tools or spiders might get confused by it. Although %2F to mean / in a path part is correct as per the standard, most of the web avoids it.
url .htaccess url-routing
如果使用这种方式可以使用 %2F ?param1=value1¶m2=value%2Fvalue 但如果使用 /param1=value1/param2=value%2Fvalue 则会抛出错误。
相关:Is a slash (“/”) equivalent to an encoded slash (“%2F”) in the path portion of an HTTP URL
【参考方案1】:
出于安全原因,Apache 拒绝路径部分中带有 %2F
的所有 URL:由于 PATH_INFO
环境变量,脚本无法正常(即不重写)区分 %2F
和 /
自动进行 URL 解码(这很愚蠢,但它是 CGI 规范的长期组成部分,因此无能为力)。
您可以使用 AllowEncodedSlashes
指令关闭此功能,但请注意,其他 Web 服务器仍将禁止此功能(没有关闭该功能的选项),并且其他字符也可能是禁忌(例如 %5C
),并且特别是 %00
将始终被 Apache 和 IIS 阻止。因此,如果您的应用程序依赖于能够在路径部分包含 %2F
或其他字符,您将限制您的兼容性/部署选项。
我在准备搜索 URL 时使用 urlencode()
您应该使用rawurlencode()
,而不是urlencode()
来转义路径部分。 urlencode()
命名错误,它实际上是针对查询字符串或 POST 请求正文中的 application/x-www-form-urlencoded
数据,而不是针对 URL 的其他部分。
不同之处在于+
并不意味着路径部分中的空间。 rawurlencode()
将正确生成 %20
,这将适用于表单编码数据和 URL 的其他部分。
【讨论】:
啊,这就是斜线被拒绝的原因。完善的诊断和治疗。 +1 我尝试在他的一个其他问题中解释其中的一些内容,但你做的比我能做的更连贯。 嗨 Bobince,rawurlencode()
也将正斜杠转换为 %2F
,这仍然会破坏我的 URL。我实际上不明白rawurlencode()
是如何解决我的问题的。
它没有,这是+
与%20
的一个附带问题。修复程序是AllowEncodedSlashes
,尽管依赖它会降低您部署的可能性(即,您无法在 IIS 上部署它,而其他用户(如果有的话)将无法部署它,如果他们使用共享主机无法访问httpd.conf
)。还有一些工具或蜘蛛可能会被它弄糊涂。尽管按照标准,路径部分中的%2F
表示/
是正确的,但大多数网络都避免使用它。
是的,查询字符串中必须允许任何编码字节序列。虽然根据 URL RFC,任何编码字节在路径组件中在技术上都是有效的,但由于路径部分传统上用于文件名,服务器会遇到其中一些问题。除了%00
、%2F
和%5C
之外,IIS 还会在路径中的非 ASCII 字节序列不是有效的 UTF-8 序列时给您带来麻烦。【参考方案2】:
在 Apache 中,AllowEncodedSlashes On 会阻止请求立即被 404 拒绝。
关于如何解决这个问题的另一个想法。
【讨论】:
【参考方案3】:在我的主机帐户上,此问题是由自动为所有帐户设置的 ModSecurity 规则引起的。在我报告此问题后,他们的管理员迅速为我的帐户删除了此规则。
【讨论】:
【参考方案4】:如果这样使用,你可以使用%2F
:?param1=value1&param2=value%2Fvalue
但是如果你使用/param1=value1/param2=value%2Fvalue
,它会抛出一个错误。
【讨论】:
【参考方案5】:$encoded_url = str_replace('%2F', '/', urlencode($url));
【讨论】:
【参考方案6】:此问题的标准解决方案是通过将可能包含斜杠的参数设置为 url 中的最后一个参数来允许使用斜杠。
对于产品代码网址,您将拥有...
mysite.com/product/details/PR12345/22
对于您想要的搜索词
http://project/search_exam/0/search_subject/0/keyword/Psychology/Management
(这里的关键词是心理学/管理)
处理第一个“命名”参数然后将剩余的参数连接为产品代码或关键字并不是大量工作。
一些框架在其路由定义中内置了此功能。
这不适用于涉及我包含斜杠的两个参数的用例。
【讨论】:
【参考方案7】:url编码后用%252F替换%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]
资源
http://www.leakon.com/archives/865
【讨论】:
非常感谢,我的问题是没有NE标志。【参考方案8】:我对带有正斜杠的 URL 部分使用 javascript encodeURI() 函数,应该将其视为字符而不是 http 地址。 例如:
"/api/activites/" + encodeURI("?categorie=assemblage&nom=Manipulation/Finition")
见http://www.w3schools.com/tags/ref_urlencode.asp
【讨论】:
问题在于在将 URI 编码为 %2F 后对其进行处理 - 请参阅已接受的答案Apache denies all URLs with %2F in the path part
【参考方案9】:
使用不同的字符并替换服务器端的斜杠
例如Drupal.org 使用 %21(感叹号字符!)来表示 url 参数中的斜线。
以下两个链接都有效:
https://api.drupal.org/api/drupal/includes%21common.inc/7
https://api.drupal.org/api/drupal/includes!common.inc/7
如果您担心字符可能与参数中的字符发生冲突,请使用字符组合。
所以你的网址是 http://project_name/browse_by_exam/type/tutor_search/keyword/one_-!two/new_search/1/search_exam/0/search_subject/0
用js改出来,转回斜线服务器端。
【讨论】:
【参考方案10】:我在 url get param 中遇到了同样的问题,在我的情况下,以下 php 代码有效:
$value = "hello/world"
$value = str_replace('/', '/', $value;?>
$value = urlencode($value);?>
# $value is now hello%26%2347%3Bworld
我首先将斜杠替换为 html 实体,然后进行 url 编码。
【讨论】:
【参考方案11】:我通过使用 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);
干杯!
【讨论】:
【参考方案12】:使用base64_encode对我来说很简单
$term = base64_encode($term)
$url = $youurl.'?term='.$term
解码后
$term = base64_decode($['GET']['term'])
这样编码“/”和“\”
【讨论】:
【参考方案13】:这是我的拙见。 !!!!别 !!!!更改服务器上的设置以使您的参数正常工作。当您更改服务器时,这是一个等待发生的定时炸弹。
我发现的最佳方法是将参数转换为 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);
【讨论】:
以上是关于urlencoded 正斜杠正在破坏 URL的主要内容,如果未能解决你的问题,请参考以下文章