Apache 2.4 expr - 如何通过 RewriteRule 加载 html 文件?

Apache 2.4 expr - 如何通过 RewriteRule 加载 html 文件?

在 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]

相关内容