【问题标题】:Site accessible with multiple URLs可通过多个 URL 访问的站点
【发布时间】:2019-03-26 14:01:27
【问题描述】:

我在托管在 VPS 上的网站上使用微框架 Silex。

因此,站点文件位于 /site_name/public_html/ 文件夹中,但对于 Silex,站点必须指向 /site_name/public_html/web/ 文件夹。

public_html 目录中,我有以下.htaccess 文件:

Options -Indexes -MultiViews

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /

    # Redirect to https & www
    RewriteCond %{HTTPS} off [OR]
    RewriteCond %{HTTP_HOST} !^www\. [NC]
    RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L,NE]

    # Redirect incoming URLs to web folder
    RewriteCond %{REQUEST_URI} !web/
    RewriteRule (.*) /web/$1 [L]
</IfModule>

并且,在/public_html/web/ 文件夹中,以下.htaccess

<IfModule mod_rewrite.c>
    # Redirect incoming URLs to index.php
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [QSA,L]
</IfModule>

现在,一切正常,但我的页面可以通过三种不同的模式访问:

  1. example.com/page/(我想保留的那个)
  2. example.com/web/page/
  3. example.com/web/index.php/page/

我已使用元规范来避免重复内容,但我仍然希望最后两个选项不存在。

我想我在两个 .htaccess 文件中都有一些要更改的内容,但我找不到它是什么。

【问题讨论】:

    标签: .htaccess redirect mod-rewrite url-rewriting silex


    【解决方案1】:

    我实际上会完全删除/web 子目录中的.htaccess 文件,并直接重写到根.htaccess 文件中的/web/index.php。通过拥有两个 .htaccess 文件,您似乎正在创造额外的工作。子目录中的 mod_rewrite 指令将完全覆盖父指令(默认情况下),因此您的规范 HTTPS 和 www 重定向也将被覆盖。

    (大概你在/web/.htaccess 文件中有一个RewriteEngine On 指令?)

    删除 /web/.htaccess 文件后,在您的根 .htaccess 文件中尝试以下类似操作:

    Options -Indexes -MultiViews
    
    RewriteEngine On
    RewriteBase /web
    
    # Redirect to https & www
    RewriteCond %{HTTPS} off [OR]
    RewriteCond %{HTTP_HOST} !^www\. [NC]
    RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=302,L,NE]
    
    # If /web or /index.php is present at the start of the requested URL then remove it (via redirect)
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^(?:web|index\.php)/(.*) /$1 [R=302,L]
    
    # Front-controller...
    # Internally rewrite all requests to /web/index.php (uses RewriteBase set above)
    RewriteRule index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
    

    REDIRECT_STATUS 环境变量的检查确保我们只测试初始请求,而不是后来重写的请求。

    &lt;IfModule&gt; 包装器不是必需的,除非您的网站打算在没有 mod_rewrite 的情况下工作。

    请注意,像/web/index.php/page/ 这样的请求会导致两次重定向。首先是/index.php/page,然后是/page。由于这是一个边缘情况,我认为双重重定向是可以接受的。

    更新:我已经删除了上面的“目录”检查,因为这会阻止文档根 (example.com/) 被重写到 /web 子目录。如果您的站点的文档根目录中没有目录索引文档(例如index.php),这将因此导致 403。 (但是,example.com/page/ 的请求应该仍然可以正常工作。)

    使用 302(临时)重定向进行测试,只有在您确定它工作正常时才更改为 301(永久) - 以避免浏览器中出现任何缓存问题。测试前请务必清除浏览器缓存。

    【讨论】:

    • 我也认为使用单个 .htaccess 文件会更好。但是,使用上面的代码,我有一个 403 Forbidden 错误...谢谢您的帮助。编辑:另外,您能告诉我为什么您将 https 重定向从 301 更改为 302?
    • 啊,是文档根目录的403,即。 example.com/?您需要删除检查它不是目录的RewriteCond 指令。 302 仅用于测试(对不起,我的意思是添加一个注释)。我已经更新了我的答案。
    • 很遗憾,它仍然无法正常工作...该页面正在显示,但未找到图像和样式。 example.com/web/ 重定向到 example.com,但 example.com/web/index.php 重定向到 example.com/index.php(404 错误)。再次感谢您的帮助。
    猜你喜欢
    • 2020-05-05
    • 2013-02-22
    • 2019-04-07
    • 2014-12-16
    • 2019-12-29
    • 2014-03-15
    • 2015-12-06
    • 2011-03-26
    • 2020-11-29
    相关资源
    最近更新 更多