![Apache 2.4 expr - 如何通过 RewriteRule 加载 html 文件?](https://linux22.com/image/784953/Apache%202.4%20expr%20-%20%E5%A6%82%E4%BD%95%E9%80%9A%E8%BF%87%20RewriteRule%20%E5%8A%A0%E8%BD%BD%20html%20%E6%96%87%E4%BB%B6%EF%BC%9F.png)
在 Apache 2.4 上,电子商务网站上有一堆混合的 SEO 友好和动态 URL,我想为我的博客文章和产品页面实现一个简单的缓存系统。首先,我想要 md5(REQUEST_URI+QUERY_STRING),然后加载预渲染的 /cache/md5hashumfile.html,仅此而已。
这是我的 htaccess 代码:
RewriteEngine on
RewriteBase /subfolder/
RewriteCond "expr=%{DOCUMENT_ROOT}/subfolder/cache/%{md5:%{REQUEST_URI}?%{QUERY_STRING}}\.html" -f
RewriteRule ^(.*)$ /cache/%{md5:%{REQUEST_URI}?%{QUERY_STRING}}\.html [L]
当我做
Header set foo-doc-root "expr=%{DOCUMENT_ROOT}/subfolder/cache/%{md5:%{REQUEST_URI}?%{QUERY_STRING}}\.html"
#Outputs
foo-doc-root: /home/user/public_html/subfolder/cache/f427ac3f86b93f6869ef8c2ce847dbd6.html
我可以在标题中验证路径是否正确,并且文件是否恰好存在于我期望的位置。
我可以验证我的 URL 的 md5 总和是否相同
Header set foo-uri "expr=%{REQUEST_URI}?%{QUERY_STRING}\.html"
哪些地方可以改进?
答案1
RewriteBase /subfolder/ RewriteCond "expr=%{DOCUMENT_ROOT}/subfolder/cache/%{md5:%{REQUEST_URI}?%{QUERY_STRING}}\.html" -f RewriteRule ^(.*)$ /cache/%{md5:%{REQUEST_URI}?%{QUERY_STRING}}\.html [L]
这里有几个错误:
您正在设置
RewriteBase /subfolder/
,但是,由于您使用的是根相对,因此该规则不会使用此设置代换字符串(以斜杠开头)。因此,您似乎试图重写为错误的 URL 路径。即,/cache/...
而不是/subfolder/cache/...
。编辑:我假设此规则正在使用目录(或.htaccess
)上下文,否则此处的使用RewriteBase
完全无效。RewriteCond "expr=
- 在指令中使用 Apache 表达式时,这不是正确的语法RewriteCond
。看起来您正在使用 mod_headers 语法。使用 mod_rewrite测试字符串(第一个参数)应该是expr
,那么条件模式(第二个参数)是表达. 例如.RewriteCond expr expression
.-f
(末尾)- 同样,这不是正确的语法。当使用阿帕奇表达式,-f
运算符是表达式的一部分(条件模式) 并且必须放在第一位。(通常,当使用正常的 mod_rewrite 语法时,-f
“测试”是条件模式本身。)您不能在
RewriteRule
代换字符串。但是,你可以在前面的状况。因此,计算/捕获 md5 哈希值状况而使用反向引用。
请尝试以下操作:
RewriteBase /subfolder/
RewriteCond expr "-f '%{DOCUMENT_ROOT}/subfolder/cache/%{md5:%{REQUEST_URI}?%{QUERY_STRING}}.html'"
RewriteCond expr "'cache/%{md5:%{REQUEST_URI}?%{QUERY_STRING}}.html' =~ /(.+)/"
RewriteRule ^ %1 [L]
补充笔记:
^(.*)$
- 由于您使用的是服务器变量,因此无需捕获 URL 路径REQUEST_URI
。- 无需使用反斜杠转义文字点
RewriteRule
代换字符串——这是一个“普通字符串”,而不是正则表达式。 - 我已经从代换字符串,以便它现在将考虑到
RewriteBase
。 - 第二条指令的目的
RewriteCond
只是捕获 md5 哈希文件名(和文件路径),然后在RewriteRule
代换使用%1
反向引用。
上述代码确实需要两次调用该md5()
函数。您可以尝试以下方法将其减少到一次(并消除对 的依赖RewriteBase
,因为无论如何您都必须/subfolder
在表达式中对 进行硬编码):
RewriteCond expr "'/subfolder/cache/%{md5:%{REQUEST_URI}?%{QUERY_STRING}}.html' =~ /(.+)/"
RewriteCond expr "-f '%{DOCUMENT_ROOT}%1'"
RewriteRule ^ %1 [L]