我的 nginx.conf 中有以下内容:
location ~* /collections.*?products/([^/]+)/?$ {
rewrite ^/collections.*?products/([^/]+)/?$ /$1.html;
rewrite ^([^_]*)_([^_]*)_(.*)$ $1-$2-$3;
rewrite ^([^_]*)_(.*)$ $1-$2 permanent;
}
重写如下请求
"/collections/products/someproduct/" to "/someproduct.html"
"/collections/products/some_product/" to "/some-product.html"
"/collections/products/some_other_product/" to "/some-other-product.html"
但是,只有当最后一个重写指令(包含标志)匹配并处理时,我才能获得 301 重定向permanent
,例如我的第二个示例。在其他两个实例中,我获得了 302 临时重定向。我如何处理此位置块中的这些多个重写指令并返回 301 重定向,无论哪些匹配?如果我在所有重写指令上放置永久标志,它将在第一次匹配后停止处理。
答案1
您可以以递归方式独立地转换_
为。-
rewrite...permanent
例如:
location ~* /collections.*?products/([^/]+)/?$ {
rewrite ^(.*)_(.*)$ $1-$2 last;
rewrite ^/collections.*?products/([^/]+)/?$ /$1.html permanent;
}
rewrite
仅当第一个rewrite
无法找到更多下划线时,才会执行第二个。参见这个文件了解更多信息。
答案2
你可以将302
状态代码视为“异常”,并使用以下方法“捕获”它http://nginx.org/r/error_page。
location ~* /collections.*?products/([^/]+)/?$ {
rewrite ^/collections.*?products/([^/]+)/?$ /$1.html;
rewrite ^([^_]*)_([^_]*)_(.*)$ $1-$2-$3;
rewrite ^([^_]*)_(.*)$ $1-$2 permanent;
error_page 302 =301 @302to301;
}
location @302to301 {
return 300; # 300 is just a filler here, error_page dictates status code
#return 301 $sent_http_location;
}
该技术类似于我的301-302-重定向-w-无-http-body-text.nginx.conf, 按照有关生成没有 HTTP 响应主体的 301/302 重定向的相关问题。
请注意,在 中@302to301
,您可以在上述两个返回语句之间进行选择;但是,代码return
在该处理程序的上下文中无关紧要,因为error_page
上述指令可确保所有302
代码都更改为,301
而不管后续代码是什么。
换句话说,return
上述两个语句之间的唯一区别是 HTTP 响应主体的内容,无论如何,没有浏览器会显示 301 响应,因此,您不妨使用较短的无主体版本return 300
。