获取 API、自定义请求 headers、CORS 和 cross-origin 重定向
Fetch API, custom request headers, CORS, and cross-origin redirects
我需要使用自定义请求 headers in-browser 发出 HTTP GET 请求,并在结果流入时对其进行处理。Fetch API 非常适合此操作:
fetch('https://example.com/resource', {
method: 'GET',
headers: {
'X-Brad-Test': 'true'
},
cache: 'no-store',
mode: 'cors'
}).then((res) => {
const reader = res.body.getReader();
// etc.
});
这个效果很好。由于有自定义 headers,浏览器 pre-flights 带有 OPTIONS 请求的请求 /resource
。我已将我的服务器配置为使用 204 No Content
和以下 headers:
进行响应
Access-Control-Allow-Headers: X-Requested-With, Range, If-Range, X-Brad-Test
Access-Control-Allow-Origin: *
浏览器对此很满意,然后发出 GET 请求,服务器 returns 一个 200 OK
数据,浏览器允许我访问响应 headers和 body.
当有重定向时,问题就来了。 OPTIONS
请求成功,204 No Content
和与以前相同的 header。浏览器发出正确的 GET
请求,在服务器上我发送 302
和 Location:
header。 Chrome 抛出以下错误:
Fetch API cannot load https://example.com/resource. Redirect from 'https://example.com/resource' to 'http://some-other-origin/resource' has been blocked by CORS policy: Request requires preflight, which is disallowed to follow cross-origin redirect.
这是出乎意料的,对我来说似乎很荒谬。我希望浏览器遵循重定向,并为这个新位置做另一个 pre-flight 请求,但它没有那样做。
陌生人仍然是我可以绕过这个client-side。我可以在没有我的自定义 header 的情况下发出 HTTP 请求,通过查看响应 object 找出重定向后我结束的位置,然后使用我的自定义 header 在新目标上发出第二个请求]s。当然,这并非在所有情况下都有效,我宁愿不依赖这种技巧。我宁愿找到一个合适的方法。
两个问题:
- 允许客户端遵循重定向的正确方法是什么?我可以使用某种
Access-Control-*
header 吗?
- 为什么会有这个限制?不关注 运行 pre-flight 关注 URL?
可以避免什么安全问题
支持重定向到需要预检的请求是对 Fetch(定义 CORS)的最新更改。
https://github.com/whatwg/fetch/commit/0d9a4db8bc02251cc9e391543bb3c1322fb882f2
我相信一些实施已经开始调整他们的实施,但这需要一些时间才能影响到每个人。
我需要使用自定义请求 headers in-browser 发出 HTTP GET 请求,并在结果流入时对其进行处理。Fetch API 非常适合此操作:
fetch('https://example.com/resource', {
method: 'GET',
headers: {
'X-Brad-Test': 'true'
},
cache: 'no-store',
mode: 'cors'
}).then((res) => {
const reader = res.body.getReader();
// etc.
});
这个效果很好。由于有自定义 headers,浏览器 pre-flights 带有 OPTIONS 请求的请求 /resource
。我已将我的服务器配置为使用 204 No Content
和以下 headers:
Access-Control-Allow-Headers: X-Requested-With, Range, If-Range, X-Brad-Test
Access-Control-Allow-Origin: *
浏览器对此很满意,然后发出 GET 请求,服务器 returns 一个 200 OK
数据,浏览器允许我访问响应 headers和 body.
当有重定向时,问题就来了。 OPTIONS
请求成功,204 No Content
和与以前相同的 header。浏览器发出正确的 GET
请求,在服务器上我发送 302
和 Location:
header。 Chrome 抛出以下错误:
Fetch API cannot load https://example.com/resource. Redirect from 'https://example.com/resource' to 'http://some-other-origin/resource' has been blocked by CORS policy: Request requires preflight, which is disallowed to follow cross-origin redirect.
这是出乎意料的,对我来说似乎很荒谬。我希望浏览器遵循重定向,并为这个新位置做另一个 pre-flight 请求,但它没有那样做。
陌生人仍然是我可以绕过这个client-side。我可以在没有我的自定义 header 的情况下发出 HTTP 请求,通过查看响应 object 找出重定向后我结束的位置,然后使用我的自定义 header 在新目标上发出第二个请求]s。当然,这并非在所有情况下都有效,我宁愿不依赖这种技巧。我宁愿找到一个合适的方法。
两个问题:
- 允许客户端遵循重定向的正确方法是什么?我可以使用某种
Access-Control-*
header 吗? - 为什么会有这个限制?不关注 运行 pre-flight 关注 URL? 可以避免什么安全问题
支持重定向到需要预检的请求是对 Fetch(定义 CORS)的最新更改。
https://github.com/whatwg/fetch/commit/0d9a4db8bc02251cc9e391543bb3c1322fb882f2
我相信一些实施已经开始调整他们的实施,但这需要一些时间才能影响到每个人。