如果我去
https://example.com
,那么一切正常。但是,如果我去https://www.example.com
,那么我的静态文件都不会加载,因为它说它违背了CSP。因此,我试图将所有 www 请求重定向到非 www.
这是我的
.htaccess
代码:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^$ public/ [L]
RewriteRule (.*) public/$1 [L]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
<IfModule mod_headers.c>
Header set Content-Security-Policy: "default-src 'self'; font-src https://fonts.gstatic.com; style-src 'self' https://fonts.googleapis.com; img-src 'self'; child-src 'none';"
...
</IfModule>
解决这个问题的最佳方法之一是在 apache/httpd 的虚拟主机配置中创建一个 ServerAlias。
ServerName example.com
ServerAlias www.example.com
这将解决它,而且一些用户仍然认为访问网站需要 www。
<IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^$ public/ [L] RewriteRule (.*) public/$1 [L] RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] RewriteCond %{HTTP_HOST} ^www\.(.+) [NC] RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] </IfModule>
您的规则顺序错误(而且不正确)。规范重定向需要在内部重写到
/public
子目录(我假设您有另一个 .htaccess
文件)之前进行。如所写,他们什么也没做。而且,您的重定向应该删除 www 前缀并没有这样做,而是重定向到同一主机,这会导致重定向循环。
你的规则应该这样写:
RewriteEngine On
# Redirect www to non-www (and HTTPS)
RewriteCond %{HTTP_HOST} ^www\.(.+?)\.?$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
# Redirect HTTP to HTTPS (already non-www)
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Rewrite everything to the "public" subdirectory
RewriteRule (.*) public/$1 [L]
不需要
<IfModule>
包装器,第一条规则(即RewriteRule ^$ public/
)是多余的,因为这将由第二条规则处理。
首先通过从 www 重定向到非 www(和 HTTPS),我们将规范重定向的数量减少到最多一个。但这确实假设您不打算实施 HSTS。
如果我去
,那么我的静态文件都不会加载,因为它说它违背了CSP。https://www.example.com
可能是因为您使用
https://example.com/...
形式的绝对 URL 引用您的“静态文件”,而不是 www.example.com
.