REQUEST_URI与显式路径和文件名不匹配 [英] REQUEST_URI not matching explicit path and filename

查看:189
本文介绍了REQUEST_URI与显式路径和文件名不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

真的很困惑,因为形式和语法看起来还不错.

Really stumped, because form and syntax seem fine.

REQUEST_URI的RewriteCond与显式路径和文件名不匹配.隔离后,REQUEST_FILENAME的RewriteCond匹配就好了.我已经使用phpinfo()验证了REQUEST_URI包含前导斜杠,并且还测试了不包含前导斜杠.

RewriteCond for REQUEST_URI is not matching the explicit path and filename. When isolated, RewriteCond for REQUEST_FILENAME matches just fine. I have verified using phpinfo() that REQUEST_URI contains the leading slash, and have tested without the leading slash, also.

这里的目标是知道请求是针对此文件的,如果不存在,则抛出410.

The goal here is to know that the request is for this file and, if it doesn't exist, then throw a 410.

RewriteCond %{REQUEST_URI} ^/dir1/dir2/dir3/v_9991_0726dd5b5e8dd67a214c0c243436d131_all\.css$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ - [R=410,L]

我不想省略第一个Cond,因为我只想对与此类似的少数文件执行此操作.

I don't want to omit the first Cond, because I only want to do this for a handful of files similar to this one.

更新我

试图进行确定的测试.测试设置:

trying to get a definitive test. Test set-up:

  • testmee.txt不存在
  • 请求是针对根目录中的testmee.txt
  • 通过重定向到Google
  • 验证了request_uri是否匹配
  • 仅使用第一个Cond时
  • 无法获得410
  • (仅使用第一个Cond时,服务器提供404,而不是410)
  • (同时使用两个条件,服务器提供404,而不是410)
  • 仅使用第二个Cond即可获得410
  • testmee.txt does not exist
  • request is for testmee.txt in the root
  • verified the request_uri is matching, by redirecting to google
  • cannot get 410 when using only first Cond
  • (when using only first Cond, server serves 404, not 410)
  • (using both Conds, server serves 404, not 410)
  • CAN get 410 when using only second 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.从长远来看,可能没什么大意了.

ughh, same symptom. Might have to live with googlebot hitting 404s instead of a desired 410 for outdated css/js. No biggie in the long run, probably.

谢谢您的request_uri测试重定向.在这些测试中,一切正常.在var =重写URL中按预期返回页面名称等.

Thank you for that request_uri test redirect. Everything is working normally in those tests. Page names, etc. are returned as expected, in the var= rewrite URL.

在这一点上,我认为这必须是与文件类型扩展名相关的404内部处理.请参阅下面的提示.我有Prestashop购物车软件,它必须在文件类型上强制使用404.

At this point, I think it must be some internal handling of 404s related to the file type extensions. See clue below. I have Prestashop shopping cart software, and it must be forcing 404s on file types.

这将重定向到google(以确认模式匹配):

This will redirect to google (to affirm pattern match):

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:

This will continue to return 404 instead of 410:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^testmee\.txt$ - [NC,R=410]

作为对照测试,这将返回410:

And as a control test, this will return a 410:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*$ - [NC,R=410]

如果在上述失败的测试中文件类型为css,则不会调用我的自定义404控制器.我只是得到一个简单的404响应,没有包含我所有网站模板的自定义404.

If file type is css in the above failed test, then my custom 404 controller does not get invoked. I just get a plain 404 Response, w/o the custom 404 that is wrapped with all my site templating.

例如:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^testmee\.css$ - [NC,R=410]

恐怕我浪费了一些时间.我很抱歉.我从没想过Prestashop的代码会基于文件类型强制使用404,但是我看不到任何其他解释.我可以对其进行深入研究,也许可以在Controllers中找到正在做的事情.不过要休息一下.

I'm afraid I've wasted some of your time. My apologies. I never imagined that Prestashop's code would be forcing 404 based on file type, but I can't see any other explanation. I could dig into it and maybe find the spot in the Controllers that is doing it. Gotta take a break, though.

推荐答案

这并不是一个可靠的答案,更多的事情可以尝试帮助调试它并消除一些误解……

This isn't really a solid answer, more of a things to try to help debug this and to quash some myths...

我已经使用phpinfo()验证了REQUEST_URI包含斜杠

是的,REQUEST_URI Apache服务器变量确实包含前导斜杠.它包含完整的URL路径.

Yes, the REQUEST_URI Apache server variable does indeed contain the leading slash. It contains the full URL-path.

但是,REQUEST_URI Apache服务器变量不一定与$_SERVER['REQUEST_URI'] PHP超全局变量相同-实际上,它们根本不是一回事.这些变量之间存在一些显着差异(在某些方面,它们使用相同的名称可能有点不幸).值得注意的是,PHP超全局包含请求中的初始URL,并包含查询字符串(如果有),并且未进行%解码.而同名的Apache服务器变量包含重写的URL (不一定是请求的URL),并且不包含查询字符串,并且已被%解码.

However, the REQUEST_URI Apache server variable is not necessarily the same as the $_SERVER['REQUEST_URI'] PHP superglobal - in fact, they aren't really the same thing at all. There are some significant differences between these variables (in some ways it's perhaps a bit unfortunate they share the same name). Notably, the PHP superglobal contains the initial URL from the request and includes the query string (if any) and is not %-decoded. Whereas the Apache server variable of the same name contains the rewritten URL (not necessarily the requested URL) and does not contain the query string and is %-decoded.

因此,这就是为什么我问您是否还有其他mod_rewrite指令.您很可能发生了冲突.如果另一个指令重写了URL,则该条件将永远不会匹配(尽管PHP超全局变量建议这样做).

So, that's why I was asking whether you have other mod_rewrite directives. You could very well have had a conflict. If another directive rewrites the URL, then the condition will never match (despite the PHP superglobal suggesting that it should).

如果我将其放在顶部,Last标志将结束该行程的处理,并返回410

It seemed that if I put this at the top, the Last flag would end processing for that trip through, return the 410

此伪指令当然应该放在.htaccess文件的顶部,以避免更早地重写URL.当L标志与R=410(除3xx以外的任何东西)一起使用时,实际上是多余的-在这种情况下隐含.

This directive should certainly go at the top of the .htaccess file, to avoid the URL being rewritten earlier. The L flag is actually superfluous when used with a R=410 (anything other than a 3xx) - it is implied in this case.

然后,我将结果更改为"throw a 410",并抛出404.

Then I change the result to be "throw a 410" and it throws a 404.

这肯定是由服务器端覆盖引起的.但是在其他情况下您也可以抛出410,因此似乎可以排除这种情况.但是,如有疑问,可以在.htaccess中重置错误文档(除非您已经在使用自定义错误文档):

That can certainly be caused by a server-side override. But you are able to throw a 410 in other situations, so that would seem to rule that out. However, you can reset the error document in .htaccess if in doubt (unless you are already using a custom error document):

ErrorDocument 410 default

RewriteCond %{REQUEST_URI} ^/dir1/dir2/dir3/v_9991_0726dd5b5e8dd67a214c0c243436d131_all\.css$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ - [R=410,L]

尽管这实际上对规则的行为没有什么影响,但您不需要第一个检查REQUEST_URIRewriteCond指令.您应该改为在RewriteRule 模式中进行此检查(这样会更有效,因为它首先被处理).例如:

Whilst this doesn't really make a difference to how the rule behaves, you don't need the first RewriteCond directive that checks against the REQUEST_URI. You should be doing this check in the RewriteRule pattern instead (which will be more efficient, since this is processed first). For example:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^dir1/dir2/dir3/v_9991_0726dd5b5e8dd67a214c0c243436d131_all\.css$ - [NC,R=410]

NC标志应该是多余的.

仍然,与现有指令冲突是最可能的原因.删除所有其他指令.您仍然看到相同的行为吗?

Still, a conflict with existing directives is the most probable cause. Remove all other directives. Do you still see the same behaviour?

您可以测试REQUEST_URI服务器变量的值.您可以发出重定向并将REQUEST_URI作为URL参数传递,也可以设置环境变量(但是每次重写都需要注意REDIRECT_<var>).

You can test the value of the REQUEST_URI server variable. You could either issue a redirect and pass the REQUEST_URI as a URL parameter, or set environment variables (but you will need to look out for REDIRECT_<var> for each rewrite).

例如,在.htaccess的顶部(或尝试使用此方法的任何地方):

For example, at the top of your .htaccess (or wherever you are trying this):

RewriteCond %{QUERY_STRING} ^$
RewriteRule ^ /test.php?var=%{REQUEST_URI} [NE,R,L]

创建了一个虚拟test.php文件,以避免对错误文档的内部子请求.

Created a dummy test.php file to avoid an internal subrequest to an error document.

这篇关于REQUEST_URI与显式路径和文件名不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆