WordPress staging服务器:直接访问页面时htpasswd引发静态资源404
这个问题我之前也碰到过,本质是浏览器首次请求非首页页面时,没有给静态资源请求带上htpasswd认证凭证,导致服务器拒绝了这些资源请求,但因为WordPress的错误处理机制,返回了404而不是标准的401认证要求(这很容易误导人以为是路径问题)。当你先访问首页时,浏览器已经完成了认证,后续所有请求都会自动带上凭证,所以资源加载正常。
下面是几个靠谱的解决方法,按优先级推荐:
方法1:调整.htaccess规则顺序,确保静态资源先跳过认证(推荐)
在你的htpasswd认证规则前,先添加一段规则,让静态资源直接跳过认证检查。这样浏览器请求.css/.js/.png这类文件时,不需要先经过htpasswd验证,自然不会出现404。
打开你的.htaccess文件,在AuthType Basic这类认证规则之前,添加:
# 允许静态资源跳过htpasswd认证 <FilesMatch "\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$"> Allow from all Satisfy Any </FilesMatch>
然后保留你的htpasswd核心认证规则,比如:
AuthType Basic AuthName "Staging Environment - Restricted Access" AuthUserFile /path/to/your/.htpasswd Require valid-user
方法2:强制所有请求先经过首页认证
如果不想让静态资源公开(虽然staging环境没必要,但如果有特殊需求),可以修改WordPress的rewrite规则,让所有非首页的请求先跳转回首页一次,触发认证后再跳转到目标页面。不过这个方法体验稍差,因为会多一次跳转:
在.htaccess的RewriteEngine On下面添加:
# 未认证时强制跳转首页 RewriteCond %{HTTP:Authorization} !^Basic.* RewriteRule !^/$ /?redirect=%{REQUEST_URI} [R=302,L]
然后在主题的functions.php里添加一段代码,处理跳转回来的请求:
add_action('template_redirect', function() { if (isset($_GET['redirect']) && !empty($_GET['redirect'])) { wp_safe_redirect($_GET['redirect']); exit; } });
方法3:修改浏览器的认证缓存行为(临时调试用)
这个方法只适合本地调试,不适合给其他测试人员用:在Chrome里,打开开发者工具(F12)进入Network标签,勾选Disable cache,然后右键点击任意请求选择Clear browser cache,之后直接访问/contact-us时,浏览器会弹出认证框,输入凭证后静态资源也会正常加载。不过这只是临时解决,不是根本方案。
补充:问题根源拆解
当你直接访问/contact-us时,浏览器首先发送这个页面的请求,服务器返回401要求认证,你输入凭证后,浏览器只给这个页面的请求带上了认证头。但页面加载时并行发送的静态资源请求,此时认证流程还没完全完成,浏览器默认不会自动给这些资源请求带上认证头。服务器拒绝这些未认证的请求后,被WordPress的rewrite规则导向了index.php,最终返回了404页面,而非直观的401提示,这才造成了“资源找不到”的错觉。
内容的提问来源于stack exchange,提问作者Chin Leung

