我们在.htaccess
文件中有一些基于路径的重写规则。例如,如果URI指向/foobar/somestring
重定向到/foo/somestring
页面,但是我们也想强制通过https
加载资源。
我们可以在所有RewriteRule
s中包含https://%{HTTP_HOST}
,首先解决了更具体的URIS,但我很确定这不是必需的。
我已经浏览了Apache标志文档,但是很难找到一种方法来告诉服务器以一种方式解决scheme
并继续阅读规则和条件以解决paths
。
这是我们现在拥有的长足方法:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI} ^/foo
# Long list
RewriteRule ^foobar/(bat.*)$ https://%{HTTP_HOST}/foo/$1 [L,R=301]
RewriteRule ^foobar/(bas.*)$ https://%{HTTP_HOST}/foo/$1 [L,R=301]
# URI not found
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ https://%{HTTP_HOST}/index.php [L]
# And finally
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L,NC]
</IfModule>
非常感谢。
这里的关键问题是了解重定向和重写之间的差异。简而言之,重定向在客户端发生,更改浏览器中的URL。改写在服务器端发生,并且对浏览器/客户端是透明的。
-
重定向的一个示例是将协议从
http://
更改为https://
或添加或删除www
子域。 -
重写的一个示例将接收到
/foo-bar-bas
之类的路径,然后将其发送由服务器处理(通过ASP,Python,Php,Php,Ruby,Node.js等),然后重写它作为article.aspx?name=foo_bar_bar
或类似的东西。
您可以在上面的OP中看到,从http://
到https://
的重定向(当它位于规则块的顶部)是由于以下两个标志而在其下方的重写短路:
-
R=301
告诉浏览器:"此(a)资源已经移动,现在在此(b)位置" -
L
告诉Apache,"停止处理规则集"。 - 第三个标志,
NC
意味着忽略案例,而/?(.*)
无论如何都不敏感。
所需要的只是:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{HTTP_HOST}/$1
RewriteCond %{REQUEST_URI} ^/foobar
RewriteRule ^foobar/(bat.*)$ /foo/$1 [L,R=301]
RewriteRule ^foobar/(bas.*)$ /foo/$1 [L,R=301]
</IfModule>
令人困惑的一部分是我们使用"重写"规则来实现"重定向"(以及下面的重写。)Apache还支持mod_rewrite
模块外的重定向指令。我不确定在这里是否有效。
值得重复 @Ultimater从上方的评论进行测试时,使用302 找到状态代码,而不是301 永久移动状态带有R
标志的代码将阻止将错误的消息发送给Web爬网或(可能是您自己的)浏览器。