如何用Cro模拟Apache Rewrite规则,实现静态路由自动补全.html后缀?
模拟Apache Rewrite规则的Cro路由配置
要在Cro中复现你给出的Apache Rewrite规则,得先明确Apache规则的核心逻辑:
- 当请求的路径既不是存在的目录,也不是存在的文件时
- 如果路径中不包含点
.,则内部重写为该路径加上.html后缀的文件
基于这个逻辑,调整Cro的路由配置即可解决localhost:5000/one返回404的问题,具体实现如下:
use Cro::HTTP::Router; use Cro::HTTP::Static; use IO::Path; my $static_root = 'rendered'; my $app = route { get -> *@path { # 构建原始请求对应的文件/目录路径 my $target_path = IO::Path.new($static_root, |@path); # 情况1:原始路径是存在的文件或目录,直接返回静态内容 if $target_path.e || $target_path.d { return static $static_root, |@path, :indexes('index.html'); } # 情况2:原始路径不存在,且路径中不含点,尝试拼接.html后缀 my $has_dot = any(@path) ~~ /\./; if !$has_dot && @path.elems > 0 { # 给最后一个路径片段加上.html后缀 my @html_path = @path[0..*-2], @path[*-1] ~ '.html'; my $html_file = IO::Path.new($static_root, |@html_path); # 如果拼接后的文件存在,返回该静态文件 if $html_file.f { return static $static_root, |@html_path; } } # 情况3:所有尝试都失败,返回404 return status 404, content 'text/plain', 'Not Found'; } };
代码逻辑说明
- 原始路径检查:先判断请求的路径是否对应已存在的文件或目录,和原有Cro逻辑一致,确保正常的静态文件/目录访问不受影响。
- 重写规则匹配:当原始路径不存在时,检查路径中是否包含点(对应Apache规则的
^([^\.]+)$匹配条件),若不包含点则尝试给最后一个路径片段添加.html后缀。 - 文件存在性验证:验证拼接后的
.html文件是否存在,存在则返回该文件内容,否则返回404。
这样配置后,访问localhost:5000/one会自动返回rendered/one.html的内容,和Apache的Rewrite规则行为完全一致;访问localhost:5000/仍会返回index.html,带后缀的路径(如localhost:5000/two.html)也能正常访问。
内容的提问来源于stack exchange,提问作者Richard Hainsworth
相关产品推荐
相关产品推荐

