我在我的httpd.conf中的virtualhost部分(Apache)有以下htaccess重写规则。如果请求只是<filename>
而没有<extension>
,Apache将根据请求头中的HTTP_ACCEPT计算返回哪个文件。在目录/images中,只有.avif、.webp和.jpeg文件,每个文件名对应一个版本。
<Directory "/var/www/<document root>/images">
RewriteEngine On
RewriteCond %{HTTP_ACCEPT} image/avif
AddType image/avif .avif
RewriteRule ^([^\.]+)$ $1.avif [L]
RewriteCond %{HTTP_ACCEPT} image/webp
AddType image/webp .webp
RewriteRule ^([^\.]+)$ $1.webp [L]
AddType image/jpeg .jpeg
RewriteRule ^([^\.]+)$ $1.jpeg
</directory>
因此,如果文件没有被前两个RewriteCond捕获,它将接收后缀. jpeg。
用https://htaccess.madewithlove.com测试它会返回完全预期的结果。而且在野外它工作得很好。
现在我已经在目录/images中放置了一个名为dm_schrift.svg
的文件,其中包含一个不同的<extension
〉。我希望请求被重写为dm_schrift. jpeg。
$ curl -s -o /dev/null -D - https://<my domain>/images/dm_schrift.svg
HTTP/2 200
date: Thu, 08 Sep 2022 09:12:19 GMT
server: Apache
x-content-type-options: nosniff
strict-transport-security: max-age=15552000; includeSubDomains
last-modified: Tue, 30 Aug 2022 18:30:12 GMT
etag: "356-5e779921d3500"
accept-ranges: bytes
content-length: 854
vary: Accept-Encoding,User-Agent
cache-control: max-age=31536000, public, immutable
content-type: image/svg+xml
(关于“不可变”:如果打开一个新的浏览器窗口,禁用DevTools中的缓存,加载文件并验证它是否真的被下载了,我会得到同样的结果。
我怎么会收到dm_schrift.jpeg的文件而不是404?
**编辑:**以下是问题的一部分,已在回答中得到解决,但基于错误的假设。放弃:
关于这些重写规则的另一个问题是:有了这些,一个被请求为'something'的文件在Chrome中将被当作'something.avif'。Devtools/Network显示了包括.扩展名的完整文件名。但是这个文件名并没有包含在响应头中。文件实际上是'avif'可以从'content-type'中推导出来,但是浏览器如何知道包括.扩展名的完整文件名呢?
1条答案
按热度按时间h9a6wy2h1#
你似乎已经在开头的一段中回答了你的问题...
如果请求只是
<filename>
而没有<extension>
,Apache将评估...这遵循你的规则中的正则表达式。即
^([^\.]+)$
(* 旁白:* 这里不需要文字点上的反斜杠转义。在您的示例中,您请求的是实际的文件,带有文件扩展名,例如
/images/dm_schrift.svg
。正则表达式不匹配,因此规则不适用,因此直接提供文件。我怎么会收到dm_schrift.jpeg的文件而不是404?
这只会发生,如果你提出了最初的请求 * 没有 * 文件扩展名(如你最初所说)。
Devtools/Network显示了包括扩展名在内的完整文件名。但是响应头中没有包含该文件名。文件实际上是“avif”可以从“content-type”中推导出来,但是浏览器如何知道包括扩展名在内的完整文件名?
从你发布的规则来看,浏览器 * 不 * 知道服务器上被重写文件的完整文件名(包括文件扩展名)。浏览器只知道mime类型(例如,从
Content-Type
头)--这与文件扩展名没有任何关系。我在我的httpd.conf的virtualhost部分(Apache)中有以下htaccess重写规则。
澄清一下,您发布的规则位于
<Directory>
部分(位于virtualhost部分)中,这与规则直接位于virtualhost部分中的情况非常不同,后者可以从您的描述中推断出来。<Directory>
部分的行为与.htaccess
类似,但请注意,任何.htaccess
文件都将 * 覆盖 * 服务器配置中相应的<Directory>
部分。