Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache 将方案重定向到https并继续执行路径规则_Apache_.htaccess - Fatal编程技术网

Apache 将方案重定向到https并继续执行路径规则

Apache 将方案重定向到https并继续执行路径规则,apache,.htaccess,Apache,.htaccess,我们在.htaccess文件中有一些基于路径的重写规则。例如,如果URI指向/foobar/somestring重定向到/foo/somestring页面,但我们还希望通过https强制加载资源 我们可以在所有的RewriteRule中包含https://%{HTTP_HOST},首先处理更具体的URI,但我很确定这不必要 我已经查看了,但很难找到一种方法来告诉服务器以一种方式解决方案,并继续阅读规则和条件以解决路径 这是我们目前采取的长期做法: <IfModule mod_rewrite

我们在
.htaccess
文件中有一些基于路径的重写规则。例如,如果URI指向
/foobar/somestring
重定向到
/foo/somestring
页面,但我们还希望通过
https
强制加载资源

我们可以在所有的
RewriteRule
中包含
https://%{HTTP_HOST}
,首先处理更具体的URI,但我很确定这不必要

我已经查看了,但很难找到一种方法来告诉服务器以一种方式解决
方案
,并继续阅读规则和条件以解决
路径

这是我们目前采取的长期做法:

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

重新启动发动机
重写基/
重写cond%{REQUEST_URI}^/foo
#长长的名单
重写规则^foobar/(bat.*)$https://%{HTTP_HOST}/foo/$1[L,R=301]
重写规则^foobar/(bas.*)$https://%{HTTP_HOST}/foo/$1[L,R=301]
#找不到URI
重写cond%{REQUEST_FILENAME}-F
重写cond%{REQUEST_FILENAME}-D
重写规则^https://%{HTTP_HOST}/index.php[L]
#最后
重写cond%{HTTPS}=在…上
重写规则^/?(*)https://%{SERVER_NAME}/$1[R=301,L,NC]

非常感谢。

这里的关键问题是理解。简而言之,重定向发生在客户端,更改浏览器中的URL。重写发生在服务器端,对浏览器/客户端是透明的

  • 重定向的一个示例是将协议从
    http://
    更改为
    https://
    或添加或删除
    www
    子域

  • 重写的一个例子是接收类似于
    /foo bar bas
    的路径,然后在发送给服务器处理(通过ASP、Python、php、ruby on rails、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>

重新启动发动机
重写基/
重写cond%{HTTPS}=在…上
重写规则^/?(*)https://%{HTTP_HOST}/$1
重写cond%{REQUEST_URI}^/foobar
重写规则^foobar/(bat.*)$/foo/$1[L,R=301]
重写规则^foobar/(bas.*)$/foo/$1[L,R=301]
令人困惑的是,我们正在使用“重写”规则来实现“重定向”(以及下面的重写)。Apache还支持
mod_Rewrite
模块之外的指令。我不确定这在这里是否行得通


值得重申的是@Ultimater在上面的评论,即在测试时,使用找到的状态代码,而不是带有
R
标志的永久移动状态代码,将防止向网络爬虫或(可能是您自己的)浏览器发送错误的消息。

这对Apache来说是一项棘手的任务。就我个人而言,为了简单起见,我会硬编码
https
,并完成它。我还将所有https重定向逻辑放在404路由逻辑之前,这样用户就不会直接在浏览器中看到index.php。在测试这类东西时,请使用302重定向,这样你就不会在浏览器中出现缓存的301s而忽略这些东西。要实现这一点,请先使用普通重写,然后只在底部发出重定向。跳过标志,或者获取/设置环境变量,或者将当前URI与请求URI进行比较都可以实现这一点。实际上,没有必要将这两件事结合起来。您可以自行实现到
https
协议的重定向。原因是1。对于任何客户机,无论发送多少请求,这只需执行一次。重写是在http服务器内的另一台主机上完成的。@Ultimater为简单起见,您所说的“硬编码https”是什么意思?