【问题标题】:.htaccess headers being ignored by Apache.htaccess 标头被 Apache 忽略
【发布时间】:2019-04-15 01:05:11
【问题描述】:

我有一个网站使用与许多其他网站相同的核心 .htaccess 细节;但是这个网站没有正确加载.htaccess 指令——给出一个基本的 HTTP 标头集:

    HTTP/1.1 200 OK
    Date: Mon, 12 Nov 2018 09:34:28 GMT
    Server: Apache
    Keep-Alive: timeout=5, max=100
    Connection: Keep-Alive
    Transfer-Encoding: chunked
    Content-Type: text/html; charset=UTF-8

网站本身可以正常加载,但 .htaccess 中的附加标头没有被识别/加载。

所以.htaccess 正在被读取,对吧?

是 -- htaccess 文件包含 HTTPS 强制重定向和域名重定向(从 .co.uk 到 .com 地址(都到同一个网站帐户))

这些工作。

PHP 提供的头文件也可以正常加载

测试页面上的 PHP 标头加载正常:

<?php
header("Cache-Control: no-cache, must-revalidate");
header('Content-Type: text/html; charset=utf-8');
header("X-Clacks-Overhead: GNU Terry Pratchett");
header("Content-Language: en");
header("X-XSS-Protection: 1; mode=block");
header("X-Frame-Options: SAMEORIGIN");
header("X-Content-Type-Options: nosniff");
?>

.htaccess 中设置的相同标头没有被识别。

所以这是一个.htaccess 语法错误!

我看不到;通常带有 .htaccess error 的站点会加载 HTTP-500 错误消息,但是这里的站点在浏览器中加载没有问题。

当出现IS故意的语法错误时,错误 500 HTTP 响应会按预期返回。

好的 bozo,检查你的错误日志!

绝对;我完全同意。 Apache 错误日志为空!

您尝试过什么来解决这个问题?

  • 确认httpd.conf 允许读取.htaccess
  • 确认 mod_headers.c 已加载到服务器上
  • 注释掉并重写了各种规则,没有效果
  • 阅读 Stack Overflow 和 Server Fault 上的大量帖子(可能是 6 到 8 条) - Stackoverflow 帖子似乎不相关,或者它们的问题有明显差异。
  • 确认我的.htaccess 具有正确的许可 (0644)
  • 告诉我的员工(他是一名平面设计师)。
  • 哭着睡着了。

那么——把你的文件拿出来!让我看看魔法!

这里:

Options +FollowSymLinks
Options -Indexes
RewriteEngine On
ErrorDocument 404 /index.php?msg=404
ErrorDocument 403 /index.php?msg=403

#Set asset items to cache for 1 week.
<FilesMatch "\.(gif|jpe?g|png|ico|css|js|swf|mp3)$">
     Header set Cache-Control "max-age=1972800, public, must-revalidate"
</FilesMatch>

RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

## This does not appear to work (for either)
#Header always set Strict-Transport-Security "max-age=31536000;" env=HTTPS
Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains;" "expr=%{HTTPS} == 'on'"
Header set Expect-CT enforce,max-age=2592000

RewriteCond %{HTTP_HOST} ^(www\.)?thewebsite\.co\.uk$ [NC]
RewriteRule ^/?(.*)$ https://www.thewebsite.com%{REQUEST_URI} [R=301,L]

###
##### Seems to workdown to roughly this point.
###

#force requests to begin with a slash.
RewriteCond  %{REQUEST_URI}  !^$
RewriteCond  %{REQUEST_URI}  !^/
RewriteRule  .*              -    [R=403,L]

RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]

### This file does not exist on the directory at present. 
<Files .account-user.ini>
    order allow,deny
    deny from all
</Files>

###
#### None of these appear on assessment tools such as Security Headers 
#### Or redbot.
###
Header set Cache-Control no-cache,must-revalidate
Header set X-Clacks-Overhead "GNU Terry Pratchett"
Header set X-XSS-Protection 1;mode=block
Header set X-Content-Type-Options nosniff
Header always set X-Frame-Options SAMEORIGIN
Header set Expect-CT enforce,max-age=2592000
Header set Content-Language en
Header set Referrer-Policy origin-when-cross-origin
    
<LimitExcept GET POST HEAD>
    deny  from all
</LimitExcept>

最后,如果你能对以上所有内容进行最后总结,那真的很有帮助!

  • .htaccess 中的标头设置命令似乎不起作用。
  • 文件的所有部分在其他地方的其他实时站点上使用,没有问题。
  • 可以在 PHP 中毫无问题地设置标题
  • .htaccess 中的这些标头没有出现错误。
  • 标头似乎静默失败。
  • 没有记录 Apache 错误日志。
  • .htaccess 正在被 Apache 读取,因为其他命令(例如 mod_Rewrites)正在被执行

更新:

根据其他方(托管服务提供商)的研究,.htaccess 似乎以某种方式工作并为非 PHP 页面加载所有正确的标头

即使是普通的 PHP 页面;标题是空白的。

澄清

  • whatever.html 页面加载标题一切正常。
  • PHP 页面显示由Header("..."); 设置的标题
  • PHP 页面拒绝加载由.htaccess 设置的任何标题。这就是问题所在。

所以它看起来我的.htaccess 不能为PHP 页面设置标题。我该如何解决这个问题?

【问题讨论】:

标签: php apache .htaccess


【解决方案1】:

当作为 FastCGI 模块工作时,PHP 似乎忽略了 .htaccess 中定义的标头。

有很多关于如何解决这个问题的建议。在您的情况下,我建议您使用一个定义所有标题的文件

<?php
// file headers.php
header('Cache-Control: no-cache,must-revalidate');
header('X-Clacks-Overhead: "GNU Terry Pratchett"');
header('X-XSS-Protection: 1;mode=block');
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: SAMEORIGIN');
header('Expect-CT: enforce,max-age=2592000');
header('Content-Language: en');
header('Referrer-Policy: origin-when-cross-origin');
?>

并将其保存到您的 DocumentRoot 目录。然后将此条目添加到您的 .htaccess 文件中以将其包含在每个请求中:

php_value auto_prepend_file /var/www/html/headers.php     

测试它:

<?php
// file test.php
die("hello world");
?>

并且正在发送标头:

$ curl -I ubuntu-server.lan/test.php
HTTP/1.1 200 OK
Date: Sun, 25 Nov 2018 09:37:52 GMT
Server: Apache/2.4.18 (Ubuntu)
Cache-Control: no-cache,must-revalidate
X-Clacks-Overhead: "GNU Terry Pratchett"
X-XSS-Protection: 1;mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Expect-CT: enforce,max-age=2592000
Content-Language: en
Referrer-Policy: origin-when-cross-origin
Content-Type: text/html; charset=UTF-8

请记住,当您更改 .htaccess 中的标头以同时更改 headers.php 中的标头时。

希望这会有所帮助!


➥ 上一个答案

我认为此问题是由于 httpd/apache2 headers_module 未正确加载(尽管您在上述 cmets 之一中另有说明)。您可以通过在终端中执行以下命令来检查这一点:

apachectl -M | grep headers_module

如果您没有得到输出headers_module (shared)(或类似的),那么您必须激活 httpd/apache2 标头模块。在 CentOS 系统上,您必须在配置中加载相应的源文件(默认为 /etc/httpd/conf/httpd.conf)。

你必须添加这一行

LoadModule headers_module /usr/lib/apache2/modules/mod_headers.so

然后用sudo systemctl restart httpd.service重启http服务器

在 EasyApache 4 中,httpd/apache2 模块所在的文件夹可能不同,为 /usr/lib64/apache2/modules/

我希望这会有所帮助!

【讨论】:

  • 感谢您在这里 D.joe 的帮助,但我只能给一个赏金,而且您得出的结论与 covener 非常相似,他们已经明白了——它是FastCGI,虽然我很欣赏你的回答,但它更多的是一种解决方法,而不是使用 Fast-CGI 的解决方案。谢谢
  • @digijay 这很好用,但有一点需要注意。使用 FastCGI 处理程序是导致问题的原因。但是此评论中给出的php_value 指令是针对 mod_php 处理程序的。所以将该行添加到.htaccess 将不起作用。相反,您必须使用以下内容创建一个 PHP 配置文件(例如,.user.ini):auto_prepend_file = /var/www/html/headers.php
  • 我生命中的 4 小时试图弄清楚为什么 CORS 在 API 中排除 php 生成的服务器响应,而答案一直都在这里!该死的FastCGI!如果您在浏览器中收到消息,表明 CORS 策略已阻止来自来源 Access to XMLHttpRequest at <api source>:请求的资源上不存在“Access-Control-Allow-Origin”标头.</api> 那么这是因为您只查看 .htaccess 来设置标题。如果在 FastCGI 中强制使用 PHP,则需要使用上述解决方案在 PHP 文件中设置它
【解决方案2】:

与其说是 FastCGI,不如说是 mod_proxy_fcgi,即要求 Apache 通过将 FastCGI 传递给其他侦听器来“执行”FastCGI 的方法。

当您使用任何 mod_proxy* 模块时,根本不会处理 .htaccess,因为您充当代理并短路任何与磁盘相关的配置部分。

php-fpm 将查看请求 URL 并从磁盘读取数据,但 Apache 不是。这只是让人们感到困惑,因为它们可以在同一主机上运行,​​并且文件通常位于 httpd 可以直接提供服务的目录中。

【讨论】:

  • 我发现处理程序是原因——从 CGI 切换到 suphp 处理程序立即解决了问题。我不确定这是否与 proxy 有任何关系,但处理程序,是的。干杯
【解决方案3】:

经过大量探索,发现问题在于 PHP 处理程序——fastCGI (cgi) 处理程序没有保留标头。

更改为 suphp 处理程序立即解决了问题。

【讨论】:

  • @swa66 这是解决方案。无论我自己或其他地方找到它。其他两个答案都暗示了一个类似的解决方案(也就是要责备的快速 CGI),这实际上使它变得更加棘手......
【解决方案4】:

我有同样的问题。 请在 Linux Ubuntu 中启用cache 模块。

sudo a2enmod cache

然后运行:

sudo service apache2 start

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-06
    • 1970-01-01
    • 2015-07-29
    • 2016-08-08
    • 2023-03-25
    • 2011-07-09
    相关资源
    最近更新 更多