【问题标题】:Apache rewrite rule causes "too many redirects" for JS and CSS filesApache 重写规则导致 JS 和 CSS 文件的“重定向过多”
【发布时间】:2020-11-06 10:51:44
【问题描述】:

我正在开发一个带有自定义 CMS(由其他人编写)的项目。有一个现有的.htaccess 文件,其中包含一些条件和重写规则,其中一个将请求定向到index.php 文件。此文件加载 CMS 对象,并调用一个方法来检查 URL 是否指向现有的 CMS 页面。如果没有,用户将被重定向到 404 页面。

CMS 还允许您在基本 CMS 功能之上构建自定义模块。通常这用于用户管理和类似的东西,但是对于这个项目,客户希望能够建立一个包含数百个知识库项目的知识库,这在 CMS 中会变得一团糟。我现在为这些项目构建了一个自定义模块,它们还存储了一个 slug。我希望 URL 为 /knowledgebase/items/item-slug,但在现有配置下,这将导致重定向到 404 页面,因为就 CMS 所知,item-slug 不会导致现有 CMS 页面。这是.htaccess 文件中的当前重写部分。

# Enable the rewrite engine
RewriteEngine On
RewriteBase /domain.tld

# SSL Redirect 301 transfer the current request.
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# never rewrite for existing files, and links
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
#RewriteCond %{REQUEST_FILENAME} !-d

# For Friendly URLs
RewriteRule ^knowledgebase/items/(.*)$ index.php?knowledge_item_slug=$1 # my own RewriteRule
RewriteRule ^(.*)$ index.php [L]

在 index.php 中,我添加了以下几行来检查是否需要显示自定义知识库项

if (isset($_GET['knowledge_item_slug']) && $_GET['knowledge_item_slug'] !== '') {
    include_once(__DIR__ . '/components/knowledgebase_item.php');
    exit(0);
}

这很好用,转到knowledgebase/items/test 会按应有的方式加载测试项目。但是,添加此规则后,在硬重新加载(清除缓存)后将无法再找到 CSS 和 JS 文件,并导致控制台出现 net::ERR_TOO_MANY_REDIRECTS 错误。

我已将规则修改为RewriteRule ^kennisbank/items/(.*)$ index.php?knowledge_item_slug=$1 [C](基本上只是添加了[C] 标志),现在项目详细信息页面可以正常工作,但任何其他页面都会导致错误The requested URL /domain.tld/page was not found on this server.

我也尝试将 RewriteRule ^(.*)$ index.php 放在我自己的 RewriteRule 之上(显然没有 [L] 标志),但是我自己的根本不起作用。

我对 Apache 重写不太熟悉,知道是什么导致了这个问题吗?

【问题讨论】:

    标签: php apache .htaccess mod-rewrite


    【解决方案1】:

    问题是在检查RewriteCond 中的非文件和非目录后,您有2 个RewriteRule 规则。只有紧接的下一个RewriteRule 会受到一个或多个RewriteCond 的影响,因此最后一个规则的执行没有任何将每个请求(包括css/js/images)路由到index.php 的条件。

    你可以这样拥有你的 .htaccess:

    # Enable the rewrite engine
    RewriteEngine On
    RewriteBase /domain.tld
    
    # SSL Redirect 301 transfer the current request.
    RewriteCond %{HTTPS} !on
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
    
    # never rewrite for existing files, and links
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -l
    RewriteRule ^ - [L]
    
    # For Friendly URLs
    RewriteRule ^knowledgebase/items/(.*)$ index.php?knowledge_item_slug=$1 [L,NC,QSA]
    
    RewriteRule ^ index.php [L]
    

    Do-nothing 规则RewriteRule ^ - [L] 将跳过该行下方的任何规则,以应对上述条件,即非文件和非目录。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-30
      • 2019-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多