背景
最近在项目开发中遇到一个奇怪的问题,就是某些请求在首页时发送和接收正常,在详情页中请求会报400错误。排查参数信息发现,两者传递的参数一致。然后又对请求进行的对比,发现详情页中的Referer中包含了页面传递的参数中,有” * “。正是请求中的Referer携带的 “ * “,会导致请求报 400。
解决思路
Referer 中包含 * 导致请求报 400(Bad Request),核心原因是 * 属于 HTTP 协议中 Referer 头的非法字符,或服务器端对 Referer 格式做了严格校验(比如正则匹配拒绝含通配符的 Referer)。
发现问题后,第一时间想起,手动修改header中的Referer:
1 | // 强制覆盖浏览器的 referer 参数 |
修改后发现,请求是不报错了,但是控制台会有新的提示:

Refused to set unsafe header “Referer” 是浏览器的安全限制导致的:根据 HTTP 规范和浏览器的同源策略 / 安全机制,Referer 属于「受保护的请求头」—— 浏览器禁止前端 JavaScript 代码手动修改 / 设置这个头,仅允许浏览器根据当前页面 URL 自动生成,目的是防止恶意脚本伪造来源地址。
于是再次更换方案,既然报错的原因是由于Referer中携带” * “导致,那就对” * “进行处理,Referer是取值的当前的链接地址,那就在跳转前对参数进行encode。
1 | `¶ms=${encodeURIComponent(JSON.stringify(params))}` |
再次访问,问题解决。
解决方案
除了上述的解决方式,还有以下几种解决方案,可供参考。
前端解决方案
1、控制 Referer 不发送(最简单,兜底方案)
1 | <!-- 完全不发送 Referer 头 --> |
2、单个请求生效(精准控制)
针对特定请求配置 referrerPolicy(优先级高于 meta 标签):
1 | axios({ |
服务端处理
1、Nginx配置改造
Nginx 默认会拒绝含非法字符的 Referer 头,或 valid_referers 规则匹配失败返回 400/403。解决方法:
- 跳过 Referer 非法字符校验
1 | # 关闭非法 header 检查(允许含*的 Referer 进入业务逻辑) |
放宽 valid_referers 规则
若用 valid_referers 做防盗链,调整规则兼容含 * 的 Referer:1
2
3
4
5
6
7
8
9location / {
# 允许空 Referer、指定域名、含*的 Referer(用~* 正则匹配)
valid_referers none blocked server_names ~*\.example\.com ~*/*;
if ($invalid_referer) {
# 注释掉 return 403/400,或改为日志记录而非拒绝
# return 400;
access_log /var/log/nginx/invalid_referer.log warn;
}
}2、Apache服务器
关闭 RequestHeader严格校验
1 | # 在 httpd.conf 或 .htaccess 中 |
- 若用 mod_rewrite 校验 Referer,修改规则兼容 *:
1 | RewriteCond %{HTTP_REFERER} !^https://example\.com/.* [NC] |
3、后端应用配置
拿Java举例:
1 | <Connector port="8080" protocol="HTTP/1.1" |
Spring Boot 可通过配置文件:
1 | # application.properties |
总结
- 发起方:移除 / 编码 *,或不发送 Referer;
- 接收方:放宽服务器对 Referer 的字符校验(Nginx/Tomcat 配置),或忽略含 * 的 Referer 校验;
- 核心原则:遵循 HTTP 标准,避免在 Referer 中使用非法字符,改用合法格式或自定义头传递通配语义。

