urlencoded正斜杠正在破坏URL

时间:2010-07-13 08:07:24

标签: .htaccess url-rewriting http-status-code-404 url-encoding

关于系统

我的项目中有这种格式的网址: -

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]

在阅读搜索网址时,我正在准备搜索网址和urldecode()时使用urlencode()。

问题

只有正斜杠字符会破坏导致404找不到页面错误的网址。 例如,如果我搜索one/two,则网址为

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

13 个答案:

答案 0 :(得分:140)

出于安全原因,Apache拒绝路径部分中包含%2F的所有URL:脚本无法正常(即没有重写)告诉%2F/之间的区别PATH_INFO环境变量自动进行URL解码(这是愚蠢的,但是CGI规范的一个长期部分,所以没有什么可以做的)。

您可以使用AllowEncodedSlashes指令关闭此功能,但请注意其他网络服务器仍然会禁止它(没有选项将其关闭),其他字符也可能是禁忌(例如{。 {1}}),特别是%5C将始终被Apache和IIS阻止。因此,如果您的应用程序依赖于路径部分中包含%00或其他字符,那么您将限制兼容性/部署选项。

  

我在准备搜索网址时使用urlencode()

您应该使用rawurlencode()而不是%2F来转义路径部分。 urlencode()名称不正确,实际上是urlencode()数据,例如查询字符串或POST请求正文中的数据,而不是URL的其他部分。

不同之处在于application/x-www-form-urlencoded并不意味着路径部分的空间。 +将正确生成rawurlencode(),这将在表格编码数据和网址的其他部分都有效。

答案 1 :(得分:8)

在网址编码后将%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]

<强>资源

http://www.leakon.com/archives/865

答案 2 :(得分:4)

在Apache中,AllowEncodedSlashes On会阻止请求立即被404拒绝。

关于如何解决这个问题的另一个想法。

答案 3 :(得分:3)

$encoded_url = str_replace('%2F', '/', urlencode($url));

答案 4 :(得分:3)

我在url get param中遇到了与斜杠相同的问题,在我的情况下跟随php代码工作:

$value = "hello/world"
$value = str_replace('/', '&#47;', $value;?>
$value = urlencode($value);?>
# $value is now hello%26%2347%3Bworld

我首先用html实体替换斜杠,然后我做url编码。

答案 5 :(得分:2)

在我的托管帐户中,此问题是由自动为所有帐户设置的ModSecurity规则引起的。在我报告此问题后,他们的管理员很快就为我的帐户删除了此规则。

答案 6 :(得分:1)

使用其他字符并替换服务器端斜杠

e.g。 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

如果您担心该字符可能会与参数中的字符发生冲突,请使用字符组合。

所以你的网址会是 http://project_name/browse_by_exam/type/tutor_search/keyword/one_-!two/new_search/1/search_exam/0/search_subject/0

用js更改它并将其转换回斜杠服务器端。

答案 7 :(得分:0)

此问题的标准解决方案是通过使参数可能包含斜杠中的最后一个参数来允许斜杠。

对于产品代码网址,您将拥有...

mysite.com/product/details/PR12345/22

对于搜索字词,您有

http://project/search_exam/0/search_subject/0/keyword/Psychology/Management

(这里的关键词是心理学/管理学)

处理第一个&#34;命名的&#34;并不是一项大量的工作。参数然后将剩余的参数连接成产品代码或关键字。

某些框架在其路由定义中内置了此工具。

这不适用于涉及我包含斜杠的两个参数的用例。

答案 8 :(得分:0)

对我来说很简单,使用base64_encode

$term = base64_encode($term) 
$url = $youurl.'?term='.$term
解码术语

$term = base64_decode($['GET']['term'])

这种方式编码“/”和“\”

答案 9 :(得分:0)

这是我的拙见。 !!!!别 !!!!更改服务器上的设置以使您的参数正常工作。这是一枚定时炸弹,等待您更换服务器的某天发生。

我发现的最好方法是将参数转换为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); 

答案 10 :(得分:-1)

我使用javascript encodeURI()函数作为具有正斜杠的URL部分,应该将其视为字符而不是http地址。 例如:

"/api/activites/" + encodeURI("?categorie=assemblage&nom=Manipulation/Finition")

请参阅http://www.w3schools.com/tags/ref_urlencode.asp

答案 11 :(得分:-1)

我通过使用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 :(得分:-3)

如果以这种方式使用,您可以使用%2F
?param1=value1&param2=value%2Fvalue

但如果您使用/param1=value1/param2=value%2Fvalue,则会产生错误。