语境
遵循以下规则:
# Redirect root url to /tvs
RewriteRule ^/$ /tvs [R=301,L]
我有一个绝对重定向,例如:
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Fri, 24 Mar 2017 16:42:23 GMT
Content-Type: text/html; charset=iso-8859-1
Content-Length: 312
Location: http://www.tvsvizzera.it/tvs
Vary: Accept-Encoding
X-Node: pcache02
X-Cached: MISS
Proxy-Connection: Keep-Alive
Connection: Keep-Alive
在 rewrite.log 中我有以下内容
10.101.114.1 - - [24/Mar/2017:16:43:34 +0100] [www.tvsvizzera.it/sid#7fd446c22168][rid#7fd446d6eb48/initial] (2) init rewrite engine with requested uri /
10.101.114.1 - - [24/Mar/2017:16:43:34 +0100] [www.tvsvizzera.it/sid#7fd446c22168][rid#7fd446d6eb48/initial] (2) rewrite '/' -> '/tvs'
10.101.114.1 - - [24/Mar/2017:16:43:34 +0100] [www.tvsvizzera.it/sid#7fd446c22168][rid#7fd446d6eb48/initial] (2) explicitly forcing redirect with http://www.tvsvizzera.it/
tvs
10.101.114.1 - - [24/Mar/2017:16:43:34 +0100] [www.tvsvizzera.it/sid#7fd446c22168][rid#7fd446d6eb48/initial] (1) escaping http://www.tvsvizzera.it/tvs for redirect
10.101.114.1 - - [24/Mar/2017:16:43:34 +0100] [www.tvsvizzera.it/sid#7fd446c22168][rid#7fd446d6eb48/initial] (1) redirect to http://www.tvsvizzera.it/tvs [REDIRECT/301]
为什么 apache 明确强制重定向为绝对重定向?
问题
服务器位于执行 SSL 卸载的反向代理后面。因此,如果重定向保持相对,则相同的规则将适用于 HTTP/HTTPS 协议。但事实并非如此,当使用 https 请求时,会被重定向到 http。
我知道我可以将规则改为如下形式
RewriteRule ^/$ %{ENV:REQUEST_SCHEME}://%{HTTP_HOST}/tvs [R=permanent,L]
但我想了解这种行为。
谢谢您的解释。
答案1
全部外部重定向(R
标志)会导致 mod_rewrite 需要绝对 URL。如果您没有在RewriteRule
代换那么 Apache 将使用当前协议、服务器名称和端口。Apache(或严格地说,mod_rewrite)不会在Location:
HTTP 响应标头中发送相对 URL,希望用户代理能够解析该 URL。
(直到 2014 年 6 月(RFC 7231) 那相对的标头中的 URLLocation:
正式成为标准的一部分。因此,特别是如果您仍在使用 Apache 2.2,那么很难说 Apache 在这里做错了什么。)
如果 Apache 返回 HTTP URL(而不是 HTTPS),那么看起来 Apache 是通过 HTTP 而不是 HTTPS 提供响应。
是的,您可以使用 mod_rewrite 手动“修复” URL。但是,REQUEST_SCHEME
服务器变量可能存在相同的“问题”。如果您使用代理,则可能需要检查X-Forwarded-Proto
标头(或类似内容)以确定它是“http”还是“https”。
除了在指令本身中(有条件地)强制使用 HTTPS 之外,您还可以力量在服务器配置中使用ServerName
(和UseCanonicalName
) 指令启用 HTTPS。但是,我认为这并不可取,您需要灵活应对?
你也可以编辑标Location:
头,然后再将其发送回客户端。使用 mod_headers,您可以通过手动删除方案 + 主机名来强制使用相对 URL,如这个 StackOverflow 答案:
Header edit Location "^https?://[a-zA-Z0-9.-]+" ""
进一步参考: