【发布时间】:2020-07-05 18:29:05
【问题描述】:
我在primary.example.com 有一个站点,该站点提供一个页面,其中包含来自other.example.com 的javascript 文件
那个 javascript 向 other.example.com/data.json 发出 XHR/ajax GET 请求
我认为这是一个 CORS 请求,因为来源应该是 primary.example.com
因此,我希望 data.json 请求包含 Origin 标头。浏览器应将此添加到 javascript 请求中,因为它会转到与加载页面不同的域。
我测试过的所有浏览器(Chrome、Firefox、WebKit)都这样做。但是查看我的服务器日志,我看到很多data.json 的请求被other.example.com 的服务器拒绝,因为它们没有在请求中发送 Origin 标头。为什么会这样?
编辑
我不知道这是否相关,但我突然想到它可能是:初始页面加载是由来自其他服务器的 302 重定向触发的。
完整的流程是这样的:
在此图中,请求 ➐ 是 AJAX 请求,大部分但并非总是在请求中使用 Origin 标头发送。
【问题讨论】:
-
当有人直接导航/浏览到
https://other.example.com/data.json并在浏览器中打开它时,浏览器不会发送 Origin 标头。浏览器基本上只在由前端 JavaScript 代码发出的 ajax 请求中发送 Origin 标头。并且服务器端运行时和 HTTP 客户端(例如 curl 和 wget)从不发送 Origin 标头,除非出于某种原因您手动将 Origin 标头添加到您与它们一起发送的任何请求中。因此,如果您已将服务器配置为拒绝没有 Origin 标头的请求,那么您只允许来自前端 JavaScript 代码的 ajax 请求。 -
是的,没错。 (我已经编辑了问题以试图明确这一点。)我只想允许 ajax 请求,它是发出请求的前端 javascript。我不关心人们把这个 url 放在浏览器或 curl/httpie 等中,但错误日志表明,由于他们的浏览器没有发送,大量看起来有效的 Chrome/Windows10 用户无法访问资源前端js发出请求时的origin header。
-
详见stackoverflow.com/a/42242802/441757,但要点是:浏览器总是在前端 JavaScript 代码发出的跨域请求中发送 Origin 标头。唯一的例外是调用代码已将请求模式设置为“no-cors”。但是任何执行此操作的代码都无法实际访问响应,因此您的服务器不太可能收到来自“no-cors”模式代码的大量请求。
-
谢谢,这似乎证实了我的预期,但不是我所看到的。虽然我意识到可能还有另一个因素在起作用,但我已经为这个问题添加了更多内容。
-
如果不重复我之前写的内容,不确定还能说些什么;但更具体一点:当前端代码使用 XHR 进行跨域请求时,无论如何都会添加 Origin 标头。任何 JS 库中的任何 ajax 方法也是如此,它们几乎都构建在 XHR 之上。少数只能在 fetch 之上构建——并且 fetch 总是将 Origin 标头添加到请求中——除了一种情况,即代码指定了“no-cors”模式。请求是否在重定向之后发出没有区别。也没有任何其他因素