.htaccess 重写规则在Apache 2.2.15上无法正常工作

vcudknz3  于 2022-12-13  发布在  Apache
关注(0)|答案(1)|浏览(140)

在我的本地Linux机器上,我运行的是Apache 2.2.15服务器。我想设置一个.htaccessRewriteRule,以便在匹配某个URL查询字符串(?print=pdf&redirect=false)时设置一个响应头。
示例URL:

www.example.com/page1/?print=pdf&redirect=false

我尝试了不同的方法,但我不知道我做错了什么。正如你所看到的,我试图设置一个环境变量,当查询字符串匹配时需要设置,但它不起作用。下面是我得到的:

RewriteCond %{QUERY_STRING}e ^print=pdf&redirect=false$
RewriteRule ^(.*)$ - [E=IS_CANONICAL:1,L]
Header set Link "https://%{HTTP_HOST}e%{REQUEST_URI}e; rel=\"canonical\"" env=IS_CANONICAL

**更新:**完整的.htaccess,请访问:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

RewriteCond %{QUERY_STRING}e ^print=pdf&redirect=false$
RewriteRule ^(.*)$ - [E=IS_CANONICAL:1,L]
Header set Link "https://%{HTTP_HOST}e%{REQUEST_URI}e; rel=\"canonical\"" env=IS_CANONICAL
p5cysglq

p5cysglq1#

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

RewriteCond %{QUERY_STRING}e ^print=pdf&redirect=false$
RewriteRule ^(.*)$ - [E=IS_CANONICAL:1,L]
Header set Link "https://%{HTTP_HOST}e%{REQUEST_URI}e; rel=\"canonical\"" env=IS_CANONICAL

发布的指令存在一些问题:
1.设置IS_CANONICAL环境变量的mod_rewrite规则位于错误的位置,甚至可能没有为所需的请求进行处理(除非URL路径恰好Map到物理资产)。此规则需要在前面的重写之前 * 转到前端控制器(index.php)。即,在整个规则块和<IfModule> Package 之前 *。

  1. %{QUERY_STRING}e-RewriteCondTestString 中的尾随e与文字e匹配。您在mod_rewrite指令中使用的是mod_headers语法。此处应该仅为%{QUERY_STRING}(而不是e)。
    1.如果预期接收此查询字符串的URL受到内部重写的影响(即它不Map到物理资产,而是通过前端控制器路由),则需要在Header指令中测试REDIRECT_IS_CANONICAL,而不是IS_CANONICAL。这是因为在处理Header指令之前,重写引擎在第一次传递期间设置的任何env var都将通过使用REDIRECT_作为前缀进行重命名。(注意:这不适用于LiteSpeed服务器。)
    1.您不应该在设置env var的规则上使用L标志。否则,请求将不会通过前端控制器路由。
    次要要点:
    1.这里不需要匹配RewriteRulepattern 中的^(.*)$,因为你只需要规则成功。一个简单的^(字符串锚的开始)就足够了,而且效率更高。
    1.第一个指令块 Package 在<IfModule>部分中,但设置env var的规则却不是。如果这段代码是您自己的,那么您可能根本不应该在这里使用<IfModule> Package 器,否则,如果这是框架的一部分(看起来像标准的WordPress代码块),那么你应该保持原样。
    请尝试以下方法:
RewriteCond %{QUERY_STRING} ^print=pdf&redirect=false$
RewriteRule ^ - [E=IS_CANONICAL:1]
Header set Link "https://%{HTTP_HOST}e%{REQUEST_URI}e; rel=\"canonical\"" env=REDIRECT_IS_CANONICAL

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

您不需要在第一个规则之前重复RewriteEngine指令,因为它已经出现在文件的后面。(为了便于阅读,RewriteEngine指令应该在文件的顶部出现一次。但是,它实际上是控制整个文件的此指令的最后一次出现。因此,在第一个规则之前包括一个额外的RewriteEngine指令实际上没有任何作用。)
Header(mod_headers)指令的位置并不重要(它可以出现在文件的末尾)。因为不同的Apache模块在请求过程中是独立处理的,并且在不同的时间处理。然而,将其与设置env var的mod_rewrite规则放在一起是合乎逻辑的。

相关问题