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 这样我就摆脱了由 &param1=value1&param2=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&param2=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的主要内容,如果未能解决你的问题,请参考以下文章

python urlencode() 反斜杠处理问题

URL重写在末尾添加斜杠会破坏我的css链接

如何用反斜杠替换正斜杠

带有斜杠的 mod_rewrite 会破坏 CSS/IMG/SCRIPTS 路径

# 后正斜杠变为反斜杠

在 Windows 批处理文件中将反斜杠更改为正斜杠