ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

JavaScript.info 跨域请求探秘:为什么有了 Referer 还需要 Origin 头

JavaScript.info 跨域请求探秘:为什么有了 Referer 还需要 Origin 头 文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载跨域Cross-Origin请求是浏览器安全模型的基石而Origin与Referer是两个极易混淆的 HTTP 请求头Referer携带完整页面 URL信息量显然更大那为什么浏览器还要额外发明并强制保证Origin本篇以现代 JavaScript 教程中「Fetch: Cross-Origin Requests」的配套问答为骨架结合仓库中 fetch 基础章节 与 fetch 选项章节 的源码级文档系统梳理Referer的不可靠性、Origin的设计初衷以及浏览器作为可信中介在 CORS 中如何利用Origin完成跨域安全校验。读完你将彻底理解两个头的职责边界并掌握用referrer/referrerPolicy控制Referer的实战方法。问题背景请求头里同时出现的两个「来源」当从http://javascript.info/some/url页面发起对http://google.com的fetch请求时浏览器发送的 HTTP 请求头大致长这样Accept: */* Accept-Charset: utf-8 Accept-Encoding: gzip,deflate,sdch Connection: keep-alive Host: google.com Origin: http://javascript.info Referer: http://javascript.info/some/url如你所见Referer和Origin同时出现。这里自然引出两个问题既然Referer包含了更完整的信息完整 URL 带路径为什么还需要Origin是否存在Referer或Origin缺失、甚至不正确的可能核心解答因为 Referer 不可靠所以需要 Origin答案的第一层很简单我们需要Origin因为Referer有时会缺席。原文档给出的结论可以用四个事实支撑HTTPS→HTTP 场景下Referer直接消失当从 HTTPS 页面更安全的协议fetch一个 HTTP 页面较不安全的协议时浏览器会省略Referer。这是「从更安全的环境访问较不安全环境」时的隐私保护策略而Origin依然照常发送。Content Security Policy内容安全策略可能禁止发送Referer站点可以通过 CSP 指令禁止请求携带Referer头此时它自然缺席。fetch本身提供了关闭甚至篡改Referer的选项如后文所述referrer: 可让fetch完全不发送Refererreferrer选项甚至允许在同源范围内修改它的值。按规范Referer本来就是可选 HTTP 头RFC 规范中Referer是 optional 的任何实现都可以选择不发送。正因为Referer不可靠Origin才被发明出来——对于跨域请求浏览器保证发送正确的Origin。换句话说Origin是浏览器层面的强保证Referer只是「通常存在、但别指望它」的辅助信息。纵深一Origin 与 Referer 的本质区别对比两个头可以更清楚地看到设计分工维度OriginReferer携带内容仅 origin协议 域名 端口不含路径完整页面 URL含路径与查询参数信息量少更克制多更暴露规范地位跨域请求由浏览器强制附加可选头可能被省略浏览器保证跨域请求保证正确不保证可能缺失、可能被策略禁止可否被脚本修改禁止forbidden header可通过referrer/referrerPolicy影响Origin的「少即是多」并非缺陷它只暴露「来自哪个站点」这一最小必要信息避免把内部路径泄漏给第三方服务器。而信息量更大的Referer因为各种原因不可靠无法承担安全校验的重任——服务器不能基于一个可能缺失、可能被篡改的头做信任决策。纵深二浏览器是 CORS 的可信中介要理解Origin的「保证」从何而来需要回到 CORS 主章节 的机制描述。只要请求是跨域的浏览器总是为它附加Origin头其值恰好是发起页面自身的 origindomain/protocol/port不含路径GET /request Host: anywhere.com Origin: https://javascript.info ...在跨域请求的整个生命周期中浏览器扮演着「可信中介」的双重角色发送侧保证确保跨域请求带上正确的Origin头脚本无法伪造接收侧检查检查响应中是否存在匹配的Access-Control-Allow-Origin头允许的具体 origin 或*若存在则把响应交给 JavaScript否则报错。正因为浏览器是唯一能「保证 Origin 正确」的一方服务器端 CORS 校验才得以建立在Origin之上。这一完整交互流程可以直观地用主章节的示意图说明纵深三为什么脚本无法伪造 Origin另一个支撑Origin可靠性的细节来自 fetch 请求头章节Fetch 规范定义了一批forbidden HTTP headers禁止请求头脚本无法通过headers选项设置其中包括Accept-Charset、Accept-EncodingAccess-Control-Request-Headers、Access-Control-Request-MethodConnection、Content-Length、Cookie、Cookie2、Date、DNTExpect、Host、Keep-AliveOriginRefererTE、Trailer、Transfer-Encoding、Upgrade、ViaProxy-*、Sec-*等注意Origin和Referer都在禁止列表中这些头「确保正确且安全的 HTTP」因此由浏览器独占控制。这从实现层面解释了为什么浏览器能「保证」Origin正确——脚本根本没有途径覆盖它。而Referer虽然同样禁止脚本直接设置却可以缺失或被 CSP 拦截这正是它与Origin可靠性差异的根源。实战用 referrer / referrerPolicy 控制 Referer理解了「为什么需要 Origin」再看 fetch-api 的 referrer 章节 中管理Referer的两个选项思路就清晰了——既然Referer本就不可靠网站完全可以主动决定它的行为。referrer选项精确控制单个请求的 Referer设为空字符串完全不发送Referer头fetch(/page, { referrer: // 不发送 Referer 头 });设为当前 origin 内的任意 URL替换Referer的值注意仅限当前 origin 内跨 origin 无法设置fetch(/page, { // 假设当前页面位于 https://javascript.info // 可以设置任意 Referer但仅限当前 origin 内 referrer: https://javascript.info/anotherpage });referrerPolicy选项按请求类型设定通用规则与精确设置单个值不同referrerPolicy告诉浏览器对不同类型请求采用何种策略。请求分为三类同源请求、跨源请求、HTTPS→HTTP从安全协议到不安全协议请求。可用值与效果如下值同源请求跨源请求HTTPS→HTTPno-referrer不发送不发送不发送no-referrer-when-downgrade完整完整不发送origin仅 origin仅 origin仅 originorigin-when-cross-origin完整仅 origin仅 originsame-origin完整不发送不发送strict-origin仅 origin仅 origin不发送strict-origin-when-cross-origin默认完整仅 origin不发送unsafe-url完整完整完整典型场景某个后台管理区存在不希望外部站点得知的 URL 结构默认策略下跨域请求会把完整 URL 放进Referer如Referer: https://javascript.info/admin/secret/paths。此时可用fetch(https://another.com/page, { // ... referrerPolicy: origin-when-cross-origin // Referer 只保留 origin 部分 });这样第三方站点只能看到https://javascript.info看不到路径。注意该策略是全局性的——不仅作用于fetch也可通过Referrer-PolicyHTTP 响应头为整页设置默认策略或通过a relnoreferrer逐链接控制。总结Origin的存在是为了弥补Referer的不可靠Referer是可选头可能因 HTTPS→HTTP 降级、CSP 策略或fetch的referrer选项而缺失规范上也不强制其存在。跨域请求的Origin由浏览器保证正确它只携带 origin 三要素协议/域名/端口且属于 forbidden header脚本无法伪造浏览器作为可信中介既负责附加正确的Origin又负责核对响应中的Access-Control-Allow-Origin决定是否放行。服务器应基于Origin而非Referer做跨域信任决策前者是强保证后者只是「通常存在」的弱信息。想主动管理Referer可在fetch中使用referrer: 移除它、referrer同源替换它或用referrerPolicy按请求类型设定规则——这些实践均可在本仓库的 CORS 主章节、fetch 请求头章节 与 fetch-api 章节 中逐一验证。赞分享文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载相关推荐Windows 1 分钟搞定 iPhone USB 网络共享苹果驱动免装 iTunes 的终极避坑指南Windows 1 分钟搞定 iPhone USB 网络共享苹果驱动免装 iTunes 的终极避坑指南 深夜的机场候机厅手机电量只剩 10%Wi Fi 弱开发工具Kubernetes 服务网格技术对比为什么有了 K8s 还需要 Service MeshKubernetes 服务网格技术对比为什么有了 K8s 还需要 Service Mesh 服务网格Service Mesh是 Kubernetes 生态教程云原生容器编排为什么你的Laravel API需要CORS跨域请求的终极解决方案为什么你的Laravel API需要CORS跨域请求的终极解决方案 在现代Web开发中跨域资源共享CORS已经成为构建API时不可忽视的关键技术。特别是后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表