真的很困惑,因为形式和语法看起来还不错。
REQUEST_URI的RewriteCond与显式路径和文件名不匹配。隔离时,REQUEST_FILENAME的RewriteCond匹配得很好。我已经使用phpinfo()验证了REQUEST_URI包含前导斜杠,并且还测试了不包含前导斜杠。
这里的目标是知道请求是针对此文件的,如果不存在,则抛出410。
RewriteCond %{REQUEST_URI} ^/dir1/dir2/dir3/v_9991_0726dd5b5e8dd67a214c0c243436d131_all\.css$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ - [R=410,L]
我不想省略第一个Cond,因为我只想对与此类似的少数文件执行此操作。
更新我
试图进行确定的测试。测试设置:
RewriteCond %{REQUEST_URI} ^/testmee\.txt$
#RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ - [R=410,L]
与
#RewriteCond %{REQUEST_URI} ^/testmee\.txt$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ - [R=410,L]
UPDATE II
对怀特先生的回应:
哦,同样的症状。可能必须与googlebot一起使用404,而不是过时的CSS / JS所需的410。从长远来看,可能没什么大意了。
谢谢您的request_uri测试重定向。在这些测试中,一切正常。在var =重写URL中按预期返回页面名称等。
在这一点上,我认为这必须是与文件类型扩展名相关的404内部处理。请参阅下面的提示。我有Prestashop购物车软件,它必须在文件类型上强制使用404。
这将重定向到google(以确认模式匹配):
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^testmee\.txt$ http://www.google.com/ [L]
(L flag is needed or else other Rules further down will interfere.)
这将继续返回404而不是410:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^testmee\.txt$ - [NC,R=410]
作为对照测试,这将返回410:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*$ - [NC,R=410]
如果在上述失败的测试中文件类型为css,则不会调用我的自定义404控制器。我只是收到一个简单的404响应,没有包含我所有网站模板的自定义404。
例如:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^testmee\.css$ - [NC,R=410]
恐怕我浪费了一些时间。我很抱歉。我从没想过Prestashop的代码会基于文件类型强制使用404,但是我看不到任何其他解释。我可以深入研究它,也许可以在Controllers中找到正在做的事情。不过要休息一下。
答案 0 :(得分:1)
这并不是一个真正的答案,更多的是试图帮助调试并打破一些神话的事情……
我已使用
phpinfo()
验证了REQUEST_URI
包含斜杠
是的,REQUEST_URI
Apache服务器变量确实包含前导斜杠。它包含完整的URL路径。
但是,REQUEST_URI
Apache服务器变量不一定与$_SERVER['REQUEST_URI']
PHP超全局变量相同-实际上,它们根本不是一回事。这些变量之间存在一些显着差异(在某些方面,它们使用相同的名称可能有点不幸)。值得注意的是,PHP超全局包含请求中的初始URL,并包含查询字符串(如果有),并且未进行%解码。而同名的Apache服务器变量包含重写的URL (不一定是请求的URL),并且不包含查询字符串,并且经过%解码。
因此,这就是为什么我问您是否还有其他mod_rewrite指令。您很可能发生了冲突。如果另一个指令重写了URL,则该条件将永远不会匹配(尽管PHP超全局变量建议这样做)。
如果我将其放在顶部,Last标志将结束该行程的处理,返回410
此伪指令肯定应该放在.htaccess
文件的顶部,以避免该URL被更早地重写。与L
(除R=410
以外的其他任何符号)一起使用时,3xx
标志实际上是多余的–在这种情况下隐含。
然后,我将结果更改为“抛出410”,并抛出404。
这肯定是由服务器端覆盖引起的。但是在其他情况下您也可以抛出410,因此似乎可以排除这种情况。但是,如有疑问,可以在.htaccess
中重置错误文档(除非您已经在使用自定义错误文档):
ErrorDocument 410 default
RewriteCond %{REQUEST_URI} ^/dir1/dir2/dir3/v_9991_0726dd5b5e8dd67a214c0c243436d131_all\.css$ RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ - [R=410,L]
尽管这并没有真正改变规则的行为,但是您不需要第一个RewriteCond
指令来检查REQUEST_URI
。您应该改为在RewriteRule
模式中执行此检查(这样做会更有效,因为它首先被处理)。例如:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^dir1/dir2/dir3/v_9991_0726dd5b5e8dd67a214c0c243436d131_all\.css$ - [NC,R=410]
NC
标志应该是多余的。
不过,与现有指令冲突是最可能的原因。删除所有其他指令。您仍然看到相同的行为吗?
您可以测试REQUEST_URI
服务器变量的值。您可以发出重定向并将REQUEST_URI
作为URL参数传递,也可以设置环境变量(但是每次重写都需要注意REDIRECT_<var>
)。
例如,在您的.htaccess
顶部(或尝试进行此操作的任何地方):
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^ /test.php?var=%{REQUEST_URI} [NE,R,L]
创建了一个虚拟test.php
文件,以避免对错误文档的内部子请求。
答案 1 :(得分:0)
我无法确定为什么服务器配置或站点代码会强制htaccess中的“ 410 Gone”响应指令被404响应覆盖,因此必须执行类似this的操作来告诉googlebot停止寻找定期清除的CSS / JS文件(并在重新生成时重命名)。
.htaccess中的
:RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule v_(.*)_(.*)$ /410response.php [L]
放在410response.php中的根目录中:
<?php header($_SERVER['SERVER_PROTOCOL'].' 410 Gone');
更新我
由于服务器显然具有自定义的410文档(显然路由到404),因此服务器强行尝试将htaccess用于410指令时的404响应。添加了一个指令以防止随后正确允许使用htaccess在RewriteRule中返回410以进行模式匹配。 (我以为我昨天已经检查了一下是否可行,因为@MrWhite在上面的回答中表示要控制可能具有自定义410的服务器;今天进行检查时,它确实起作用并指出服务器410- -404重定向覆盖了我的410指令。)
ErrorDocument 410 default
RewriteRule test\.txt$ - [NC,R=410]
怀特先生!我在Stack Exchange上的one of your posts中找到了该解决方案。