74

关于系统

我的项目中有这种格式的 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 page not found 错误。例如,如果我搜索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
4

13 回答 13

150

出于安全原因, Apache 拒绝%2F路径部分中的所有 URL:脚本通常无法区分%2F/由于PATH_INFO环境变量被自动 URL 解码(这很愚蠢,但长期存在) CGI 规范的一部分,因此对此无能为力)。

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

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

您应该使用rawurlencode(), 而不是urlencode()转义路径部分。urlencode()命名错误,它实际上是用于application/x-www-form-urlencoded查询字符串或 POST 请求正文中的数据,而不是用于 URL 的其他部分。

不同之处在于这+并不意味着路径部分中的空间。rawurlencode()将正确生成%20,这将适用于表单编码数据和 URL 的其他部分。

于 2010-07-13T08:26:24.277 回答
11

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

于 2015-02-26T11:32:26.043 回答
5

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

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

于 2011-04-28T09:27:52.847 回答
4
$encoded_url = str_replace('%2F', '/', urlencode($url));
于 2014-03-12T01:23:52.013 回答
4

我在 url get param 中遇到了同样的问题,在我的情况下,以下 php 代码有效:

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

我首先用 html 实体替换斜线,然后进行 url 编码。

于 2015-12-03T17:46:44.413 回答
3

以下是我的拙见。!!!!不 !!!!更改服务器上的设置以使您的参数正常工作。当您更改服务器时,这是一个等待发生的定时炸弹。

我发现的最好方法是将参数转换为 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); 
于 2019-04-27T20:15:28.953 回答
2

在我的主机帐户上,此问题是由自动为所有帐户设置的 ModSecurity 规则引起的。在我报告此问题后,他们的管理员迅速为我的帐户删除了此规则。

于 2011-05-17T18:03:37.530 回答
1

使用不同的字符并替换斜杠服务器端

例如 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把它改出来,然后转换回斜线服务器端。

于 2015-09-02T15:49:45.623 回答
1

对我来说很简单,使用 base64_encode

$term = base64_encode($term) 
$url = $youurl.'?term='.$term

在你解码这个词之后

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

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

于 2017-06-13T16:33:39.690 回答
0

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

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

mysite.com/product/details/PR12345/22

对于您拥有的搜索字词

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

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

处理第一个“命名”参数然后将剩余的参数连接为产品代码或关键字并不是大量工作。

一些框架在其路由定义中内置了此功能。

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

于 2014-11-07T11:51:20.080 回答
-1

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

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

http://www.w3schools.com/tags/ref_urlencode.asp

于 2015-04-22T17:21:35.283 回答
-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);

干杯!

于 2016-10-02T21:13:35.643 回答
-3

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

但是如果你使用/param1=value1/param2=value%2Fvalue它会抛出一个错误。

于 2011-11-20T15:01:39.677 回答