[浏览器] XMLHttpRequest/fetch 有办法构造出所谓的“简单请求”吗?

2024-07-17 08:32:37 +08:00
 justdoit123

看了 MDN 的文档 -- CORS Simple Reqeusts,按这一句说明:

If the request is made using an XMLHttpRequest object, no event listeners are registered on the object returned by the XMLHttpRequest.upload property used in the request; that is, given an XMLHttpRequest instance xhr, no code has called xhr.upload.addEventListener() to add an event listener to monitor the upload.

看着感觉可以用 XMLHttpRequest 构建一个不被 CORS 拦截的简单请求。但是试了几次,感觉都成功不了。

比如下面这段 js ,在 ex.noerr.eu.org 的 web console 下执行的时候,会被 CORS 拦截下来。

    const http = new XMLHttpRequest()
    http.onreadystatechange = function() {
      if (this.readyState === 4 && this.status === 200) {
        console.log( http.responseText);
      }
    }
    http.open('GET', 'https://www.google.com/js/bg/7ggH1mMGEukBBwoLB3EX4ZHW7ZyTei_QLMtxr-2MQIA.js', true);
    http.send();

如果 XMLHttpRequest/fetch 无法构造出简单请求,这个文档就没必要提起,直接说这两类请求都不是简单请求即可了。所以挺疑惑的。

当然了,构造这种请求似乎没有什么使用价值,大家不用在使用 CORS 上费口舌,仅做解惑。

2035 次点击
所在节点   科技
12 条回复
okakuyang
2024-07-17 08:38:59 +08:00
简单请求只是不触发预检,所有从脚本中发起的请求都应该是遵循同源规则,
Bingchunmoli
2024-07-17 08:41:22 +08:00
imdong
2024-07-17 08:43:08 +08:00
说白了,同源检测最终目的是为了安全,不是为了给你添麻烦。

所以,安全这事怎么可能留口子给你跳过。
rabbbit
2024-07-17 08:48:45 +08:00
那个简单请求是为了兼容以前的表单
estk
2024-07-17 08:52:16 +08:00
用自己开发的浏览器可以
sagaxu
2024-07-17 08:57:21 +08:00
1 楼已经揭秘,

Some requests don't trigger a CORS preflight. Those are called simple requests from the obsolete CORS spec, though the Fetch spec (which now defines CORS) doesn't use that term.

简单请求,它只是不触发预检,服务端收到请求做了应答,浏览器根据响应头做 CORS 校验。
HTTP/2 200
accept-ranges: bytes
content-encoding: br
content-security-policy-report-only: require-trusted-types-for 'script'; report-uri https://csp.withgoogle.com/csp/botguard-scs
cross-origin-resource-policy: cross-origin
cross-origin-opener-policy: same-origin; report-to="botguard-scs"
report-to: {"group":"botguard-scs","max_age":2592000,"endpoints":[{"url":"https://csp.withgoogle.com/csp/report-to/botguard-scs"}]}
content-length: 7450
x-content-type-options: nosniff
server: sffe
x-xss-protection: 0
date: Thu, 11 Jul 2024 10:40:23 GMT
expires: Fri, 11 Jul 2025 10:40:23 GMT
cache-control: public, max-age=31536000
last-modified: Mon, 08 Jul 2024 09:30:00 GMT
content-type: text/javascript
vary: Accept-Encoding
age: 483284
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
X-Firefox-Spdy: h2


不做预检,服务端能收到业务请求
做预检,服务端收不到业务请求
daysv
2024-07-17 09:21:51 +08:00
没弄懂楼主要解决什么问题
cat
2024-07-17 09:25:17 +08:00
@daysv 他想“用 XMLHttpRequest 构建一个不被 CORS 拦截的简单请求”
yuzo555
2024-07-17 09:29:28 +08:00
简单请求是浏览器直接先完成请求,然后直接从请求的响应头判断是否允许 CORS ,如果不允许,数据就不给你;
复杂请求是先发起一个预检查请求( OPTIONS ,如果有预检查请求的有效缓存也可以不发起),根据预检查请求的结果来判断是否允许 CORS ,允许才去做正式请求。

无论是简单请求与否,如果目标服务器不允许你跨域访问,浏览器都不会让你获取到目标资源。
daysv
2024-07-17 09:43:27 +08:00
@cat 这不是伪命题么。 要简单请求必须要服务端改造, 服务端改造那直接设 headers 不就行了吗?
cat
2024-07-17 09:44:39 +08:00
@daysv 不,换而言之,楼主想绕过浏览器的 cors 保护
justdoit123
2024-07-17 10:19:50 +08:00
不用讨论这样做 CORS 。我只是读文档,有疑惑而已。

楼上 #1, #6 说的是正解,非常感谢~ 意思就是说,简单请求 **只是** 不触发预检,并不是说这类请求能绕过 CORS 保护。

而 script 、img 、link 、form 这类标签构造出来的请求能绕过 CORS 保护,是为了 **向后兼容**。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/1057878

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX