ErrorDocument 404 vs FallbackResource vs RewriteRule

ErrorDocument 404 vs FallbackResource vs RewriteRule

通过 "copy-pasting" 来自网络但没有真正理解发生了什么,我制作了这样的 .htaccess 文件:

Options +FollowSymLinks -MultiViews -Indexes

ErrorDocument 404 /index.php?notfound=1  # (a)

FallbackResource /index.php?notfound=1  # (b)

RewriteEngine On
RewriteBase /
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url= [NC,QSA,L]  # (c)

我觉得 (a) 和 (b) 指令没有用,因为 (c)...我说得对吗?

这 3 个指令之间的真正区别是什么?

What's the real difference between those 3 directives ?

他们在这里都或多或少地做同样的事情。

ErrorDocument 404FallbackResource 都将给定的脚本设置为任何会导致 404 的处理程序,因为请求的 URI 没有映射到任何现有文件或文件夹。

我认为这里的主要区别在于,使用 ErrorDocument 404 时,您每次仍会在服务器的错误日志中获得一个条目,而使用 FallbackResource 时,则被认为暗示这是意味着成为一个前端控制器,这样就不会污染你的日志。如果您需要有关 actual 404 发生的任何信息 - 那么您必须在系统确定实际上没有找到任何可在请求的 URI。

重写版本基本上只是它的“老派”版本,FallbackResource 的文档明确提到,https://httpd.apache.org/docs/2.4/mod/mod_dir.html#fallbackresource:

It is frequently desirable to have a single file or resource handle all requests to a particular directory, except those requests that correspond to an existing file or script. This is often referred to as a 'front controller.'

In earlier versions of httpd, this effect typically required mod_rewrite, and the use of the -f and -d tests for file and directory existence. This now requires only one line of configuration.

因此对于前两个中的任何一个,您甚至不需要 mod_rewrite 可用(有时可能不需要,在便宜的共享主机或其他东西上。)

如上所示的重写版本,将在参数名称 url 下传递最初请求的 URI,因此您可以使用 $_GET['url'] 访问它。对于前两个中的任何一个,它都不会在新的内部重写 URL 中显式传递,因此您必须从服务器变量访问它,如下面几行所述,

A fallback handler (in the above case, /blog/index.php) can access the original requested URL via the server variable REQUEST_URI. For example, to access this variable in PHP, use $_SERVER['REQUEST_URI'].

使用mod_rewrite这样的事情还是有它的用处的,如果你不想把所有的请求重写到同一个脚本,或者你不想在[=55中做参数解析=] - 就像您可能想将 products/foo 重写为 products.php?product=foo 并将 profile/username 重写为 profile.php?user=username.

ErrorDocument 404FallbackResource 不允许这样做,但是 mod_rewrite 具有专门匹配这些路径段的不同规则集,可以做到这一点。

我想现在使用 FallbackResource 被大多数人认为是最先进的,并且处理 URL 的解析并根据此决定接下来需要发生什么,通常被认为更符合逻辑地放置在站点/应用程序的脚本部分,而不是将其放在单独的位置,如 .htaccess。