sec-fetch-site请求头含义解析:同域API请求为何Origin头为undefined?
收到的所有请求头逐字段含义
Origin: undefined
这不是浏览器真的发送了值为undefined的Origin请求头,是你服务器日志处理时,对不存在的请求头字段做了占位标识。
按照浏览器原生请求规则,跨域请求无论类型一定会强制携带完整的Origin头,但同源场景下的简单数据请求(比如普通fetch调用),为了减少冗余头开销,浏览器默认不会主动添加Origin头。很多开发者会以为同源请求也必然带完整Origin头,但按照fetch规范的设计,只有跨域请求、或是同源场景下会触发服务器状态变更的非简单请求,才会被浏览器强制要求携带Origin头。这个行为和你用不用cross-fetch无关——cross-fetch只是对原生fetch做了跨端封装,浏览器环境下的请求头逻辑完全遵循原生规则。sec-fetch-dest: empty
代表当前请求没有指定的资源加载上下文,不是用来加载脚本、样式表、图片、iframe这类静态资源的,就是最常见的XHR/fetch类纯数据接口请求,和你调用API的场景完全匹配。sec-fetch-mode: cors
代表当前请求受CORS规则管控,哪怕是同源请求,只要是通过fetch/XHR发起的非页面导航类请求,浏览器默认都会带这个值,不是只有跨域请求才会触发cors模式标记。sec-fetch-site: same-origin
这个是浏览器自动计算的来源匹配标记,对应规范内4个枚举值的实际差异:same-origin:发起请求的页面和目标接口的协议、域名、端口完全一致,就是你当前的场景:页面部署在https://www.example.com,接口部署在同路径下的/api/,完全符合同源判定标准same-site:发起请求的页面和目标接口的根注册域名一致,但子域、协议、端口存在差异——比如页面在https://app.example.com,接口在https://api.example.com,哪怕跨子域也会被标记为same-sitecross-site:发起请求的页面和目标接口连same-site的匹配标准都达不到,属于完全跨站的场景,比如从https://aaa.com页面发起对example.com接口的请求,就会标记为这个值none:请求无明确网页来源上下文,比如用户在地址栏直接输入地址跳转、刷新页面,或是服务端侧主动发起的请求。
两个核心判断的直接结论
- 这种标记能不能代表Origin校验已经提前由浏览器完成了?
不能。sec-fetch系列头是浏览器在网页环境下自动附加的参考值,本身不具备安全校验效力:非浏览器环境(比如脚本、爬虫、手动构造的请求)完全可以任意伪造这些头的值,不能代替后端自身的Origin校验、CORS配置逻辑。你当前看到的same-origin标记,只能说明这次请求是从你自己域名下的网页环境,通过浏览器正常fetch链路发出来的,不代表后端可以跳过安全校验环节。 - 看到
sec-fetch-site: cross-site就一定代表请求是其他第三方网站发起的吗?
在纯浏览器、无重定向的简单场景下基本成立,但存在两个需要注意的例外:- 同站点内的跨域重定向、或是从浏览器其他tab(不同站点)跳转后发起的请求,也会被标记为cross-site,并非全是恶意第三方发起
- 所有非浏览器环境的请求都可以手动伪造sec-fetch头的值,单独靠这个字段没法准确判定请求来源
内容的提问来源于stack exchange,提问作者cbdeveloper
相关产品推荐
相关产品推荐

