在某些 URL 中使用百分比编码 # 字符 (%23) 的 Yii 网站无法解析



最终编辑:看来我已经明白了!回答如下。

编辑二:我认为Apache通常是一个巨大的后顾之忧,但我无法将生产Web服务器从Litespeed(专有Apache)切换到nginx,在那里这些URL可以毫无问题地解决。但是,是的,只是作为一个注意——这些东西在nginx中运行得很好。

编辑三个:到目前为止,freenode上的一位友好伙伴已经想出了以下重写规则,他试图帮我解决一些问题:

RewriteRule ([^#]+)#([^#]+) /index.php/$1¦$2 [L,QSA,NC]

无论这个疯狂的moon语言regex看起来多么酷,它只适用于带有哈希的URL——它破坏了其他一切。有没有办法让这些重写规则在404或类似的情况下倒退?

编辑四个:有人建议:

FallbackResource /index.php

运气也不好。

原始问题:

我在一个网站上工作,它有一些URL,这些URL是从项目的标题派生的(作为标题的示例,thisUrlDerivedFromUrl-#example),看起来像这样:

http://example.com/listen/thisUrlDerivedFromItemTitle+-+%23示例-mid26372

然而,这将我带到下面的404错误页面,在那里你可以看到请求在编码为%23:的#处被切断

Error 404
Unable to resolve the request "listen/thisUrlDerivedFromItemTitle+-+"

需要明确的是,我不是在寻找花哨的AJAX URL或任何类似的东西,当我尝试在谷歌上搜索解决方案时。这只是一个特定网站上某些预先存在的项目的问题,由于URL中存在#字符,这些项目无法解决,这是一个从项目标题派生的值,人们喜欢在上传项目的标题中添加不会出现的标签和类似"我是#1"之类的东西。

因此,这里有一个关键——在Yii中,有一个选项可以使用隐藏脚本名称(index.php)

showScriptName => 'false'

config/main.php中的指令。根据站点的操作员,这是站点所需的行为。然而,我现在禁用了showScriptName,因为没有它,带有哈希的URL就无法工作,这使得URL看起来都像这样:

http://example.com/index.php/listen/thisUrlDerivedFromItemTitle+-+%23示例-mid26372

问题是,这种URL格式解析得很好,没有404混乱或类似的东西。我认为我的雇主对这种妥协不满意。

我将提供我的.htaccess,以及我在config/main.php中的urlManager数组,希望有人能找到解决这个问题的方法。为了寻求解决方案,我可以分享的任何想法或其他任何东西都是有用的,并提前表示感谢:)

.htaccess:

Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)?*$ index.php/$1 [L,QSA]

config/main.php:中的urlManager数组

'urlManager' => array(
    'urlFormat' => 'path',
    'showScriptName' => true,
    'rules' => array(
        'user/<_a:(register|update|forgottenpassword)>' => 'user/<_a>',
        'user/<username>' => 'user/view','user/<username>/<_a>' => 'user/<_a>',
        'listen/<title>-mid<id>' => 'mixtape/listen'),
),

编辑:显然,在我打开htaccess文件之前,这些URL工作得很好,在它的前一个版本中,它使facebook能够访问opengraph的静态图像文件链接。我质疑这种断言,即它以前工作得很好,这是基于对备份的测试——将其切换回旧的htaccess&代码做zilch。不过,此处仅供参考:

Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on

RewriteCond %{HTTP_REFERER} !^http://example.com/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://example.com$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.example.com/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.example.com$      [NC]
RewriteRule .*.(jpg|jpeg|gif|png|bmp|mp3|zip)$ - [NC,F,L]
RewriteBase /
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
# otherwise forward it to index.php 
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.* - [F,L]
RewriteRule ^.*$ index.php [NC,L]

我现在已经弄清楚了,这要归功于freenode上一个友好的陌生人用以下疯狂的moon语言regex解决方法将其连接起来:

RewriteRule ([^#]+)#?([^#]*) /index.php/$1$2 [L,QSA,NC]

显然,我真的不会说疯狂的月亮语,但我推断这就是它的意思:它说match$1()是不包括#([^#]表示不包括#)到#的任何字符组,然后match$2在另一边是相同的,在任何事件#之后都有通配符*。

为其他考虑过答案的人干杯!

最新更新