【问题标题】:.htaccess satisfy www/ssl rules before redirection.htaccess 在重定向之前满足 www/ssl 规则
【发布时间】:2020-06-01 12:46:27
【问题描述】:

我已经浏览了数十篇关于此的文章,但没有一篇能解决我的问题,并且一直让我头疼。

这是我想要实现的目标:
1) 我有第二个域名,需要重定向到主域,同时保留 URL 的其余部分,
2) 所有文件都应丢失 .php 扩展名,
3) 强制 WWW,
4) 强制 HTTPS。

现在的问题是,我当前的 .htaccess 仅适用于主域,并且仅在满足 WWW 条件时才有效。让我解释一下。

如果我输入 domain1.com/pagedomain2.com/page,它将打开 https://www.domain1/2.com /page.php 但它应该只是 /page 没有 .php。

如果我输入 www.domain1.com/page,它将打开 https://www.domain1.com/page - 预期行为,
但如果我输入 www.domain2.com/page,它将打开 https://domain1.com/page.php

如何确保 HTTP/HTTPS 和 WWW/非 WWW、domain1.com/domain2.com 的任何组合始终重定向到 https://www.domain1.com/page ?

我也很高兴有任何 php 代码建议,我可能会将每个 .php 文件的顶部自动重定向到无扩展名版本,但我真的很想了解为什么我的 .htaccess 不起作用。

代码如下:

## Main Rules
Options +FollowSymLinks
RewriteEngine On
RewriteBase /

## Redirect Domain2.com to Main
RewriteCond %{HTTP_HOST} ^www\.domain2\.com [NC]
RewriteRule ^(.*)$ https://www.domain1.com/$1 [R,L]

## Remove .php Extensions
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [NC,L]

## Force HTTPS
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

## Force WWW
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

ErrorDocument 404 /404

非常感谢!

【问题讨论】:

    标签: .htaccess web redirect https


    【解决方案1】:

    您的指令顺序错误。重要的是,附加 .php 扩展通过内部重写(您已标记为“删除 .php 扩展”)的规则应该放在最后,外部重定向。您的重写是将.php 附加到请求的URL,即。 page 变为 page.php 并且然后您正在触发一个外部重定向,该重定向自然会暴露底层文件名。

    但是,您的指令会导致多次重定向,并且可以简化。例如,最后一个重定向没有规范化协议(并回复之前的规则以完成此操作)。

    例如:

    ErrorDocument 404 /404
    
    ## Main Rules
    Options +FollowSymLinks -MultiViews
    RewriteEngine On
    RewriteBase /
    
    ## Redirect Domain2.com to Main
    RewriteCond %{HTTP_HOST} ^(www\.)?domain2\.com [NC]
    RewriteRule (.*) https://www.domain1.com/$1 [R,L]
    
    ## Force HTTPS
    RewriteCond %{HTTPS} off
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    
    ## Force WWW
    RewriteCond %{HTTP_HOST} !^www\.
    RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    
    ## Append .php Extensions
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME}\.php -f
    RewriteRule (.*) $1.php [L]
    

    如果您不打算实施 HSTS,则应反转“强制 HTTPS”和“强制 WWW”规则,以避免在请求 http://domain1.com/page 时额外重定向。

    请注意,您从 domain2.comdomain1.com 的初始重定向是 302(临时)重定向。

    更新:请注意,MultiViews 也应该被禁用,如果还没有的话。例如:

    Options +FollowSymLinks -MultiViews
    

    如果启用了 MultiViews,那么这也将导致第一个重定向暴露文件扩展名,因为 mod_negotiation 会为 page.php 发出一个内部子请求 mod_rewrite 处理请求之前。但是,如果启用了MultiViews,那么这也意味着附加.php 扩展名的最终重写规则被有效地绕过(因为第二个条件总是会失败,除非page.php.php 存在。)。

    禁用多视图后,这会突出显示最终重写的潜在错误。因为对/page/foo 的请求,其中/page.php 作为实际文件存在(如您的示例中所示)将由于重写循环而导致500 内部服务器错误。为了纠正这个问题,附加 .php 扩展名的最终重写规则应更改为以下内容:

    ## Append .php Extensions
    RewriteCond %{DOCUMENT_ROOT}/$1.php -f
    RewriteRule (.*) $1.php [L]
    

    (没有必要检查请求是否不是一个目录是一个文件,因为它不可能同时是两者。)

    【讨论】:

    • 不幸的是,这对我想要实现的目标没有任何影响(仍然相同 - 直接在没有 www 的情况下输入 URL 时暴露的扩展名),所以我不认为是顺序的问题。
    • 您需要清除浏览器缓存。 (301 被浏览器永久缓存。)
    • 您必须进行哪些“微调”? ....您是否需要禁用MultiViews
    • ## 附加 .php 扩展 RewriteCond %{THE_REQUEST} ^[AZ]{3,9}\ /([^\ ]+)\.php RewriteRule ^/?(.*)\. php$ /$1 [L,R=301] RewriteCond %{REQUEST_FILENAME}\.php -f RewriteRule ^/?(.*)$ /$1.php [L]
    猜你喜欢
    • 1970-01-01
    • 2017-05-09
    • 2019-02-04
    • 2012-06-11
    • 2014-11-24
    • 2017-09-23
    • 2018-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多