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

157 天前
 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 ,在 v2ex.com 的 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 上费口舌,仅做解惑。

1676 次点击
所在节点   科技
12 条回复
okakuyang
157 天前
简单请求只是不触发预检,所有从脚本中发起的请求都应该是遵循同源规则,
Bingchunmoli
157 天前
imdong
157 天前
说白了,同源检测最终目的是为了安全,不是为了给你添麻烦。

所以,安全这事怎么可能留口子给你跳过。
rabbbit
157 天前
那个简单请求是为了兼容以前的表单
estk
157 天前
用自己开发的浏览器可以
sagaxu
157 天前
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
157 天前
没弄懂楼主要解决什么问题
cat
157 天前
@daysv 他想“用 XMLHttpRequest 构建一个不被 CORS 拦截的简单请求”
yuzo555
157 天前
简单请求是浏览器直接先完成请求,然后直接从请求的响应头判断是否允许 CORS ,如果不允许,数据就不给你;
复杂请求是先发起一个预检查请求( OPTIONS ,如果有预检查请求的有效缓存也可以不发起),根据预检查请求的结果来判断是否允许 CORS ,允许才去做正式请求。

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

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

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

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

https://www.v2ex.com/t/1057878

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

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

© 2021 V2EX