You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache已验证.htaccess重写规则异常:SVG请求未按预期重写

为什么请求带扩展名的文件时Apache重写规则未触发?

问题场景

在Apache虚拟主机的httpd.conf的<Directory>段配置了基于HTTP_ACCEPT的图片格式重写规则:仅当请求为不带扩展名的文件名时,根据请求头返回对应格式的图片(avif/webp/jpeg优先级依次降低)。原本目录中只有这三种格式的文件,规则运行正常。但添加dm_schrift.svg文件后,请求https://<my domain>/images/dm_schrift.svg时,服务器直接返回了SVG文件,而非预期的重写为dm_schrift.jpeg并返回404。

原因分析

你的重写规则核心问题在于正则表达式的匹配范围:

  • 三条RewriteRule的匹配模式都是^([^\.]+)$,其中[^\.]+表示匹配完全不包含点字符的字符串。也就是说,只有像dm_schrift这种不带扩展名的请求才会被规则捕获。
  • 当请求dm_schrift.svg时,路径中包含点字符,完全不匹配规则的正则表达式,因此所有重写规则都不会执行。
  • Apache的默认行为是:如果请求的路径对应磁盘上实际存在的文件,会直接返回该文件,不会触发未匹配的重写规则。

解决方案

根据你的需求选择对应方案:

方案1:保留原规则逻辑(仅处理不带扩展名的请求)

当前行为是符合规则设计的,无需修改。带扩展名的请求会直接返回磁盘上的对应文件,这是Apache的正常机制。

方案2:强制所有请求(无论是否带扩展名)都按规则重写

如果需要让带扩展名的请求也被重写(比如把dm_schrift.svg强制转为dm_schrift.avif/webp/jpeg),需要修改正则表达式并添加防循环重写的条件:

<Directory "/var/www/<document root>/images">
    RewriteEngine On

    # 防循环:如果请求的文件已经是目标格式,直接跳过重写
    RewriteCond %{REQUEST_FILENAME} \.(avif|webp|jpeg)$
    RewriteRule ^ - [L]

    # 匹配所有请求,提取文件名部分(忽略原有扩展名)
    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>
  • ^(.+?)(\..*)?$会匹配所有请求路径,捕获文件名部分(无论后面是否带扩展名),替换为目标格式的文件名。
  • 第一条规则用于避免循环重写:如果请求的已经是avif/webp/jpeg格式的文件,直接终止重写流程。

内容的提问来源于stack exchange,提问作者jamacoe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 04:40:24