浏览器跨域请求,为什么简单请求直接就发送了,非简单请求还要先发一个 options 方法的预检请求?

2022-04-25 22:53:04 +08:00
 fstar

我觉得这是不是设计有问题。

如果我来设计的话,不分什么简单不简单请求,全都先发一个 options 。或者全都直接直接发原请求。

这样不上不下的设计真的很奇怪啊。

3098 次点击
所在节点    程序员
23 条回复
vance123
2022-04-25 22:59:20 +08:00
为了前向兼容,前端里很多奇奇怪怪的地方都是有历史原因的
sujin190
2022-04-25 23:01:50 +08:00
get 单独发浪费性能增加延迟吧,post 之类的直接发不泄露数据了吧,那你这跨域限制不废了么,这又不复杂的优化有啥难理解的
lscho
2022-04-25 23:06:15 +08:00
按你的理论,直接取消跨域就完事了。
wwqgtxx
2022-04-25 23:07:49 +08:00
总有人觉得自己能在十几年前预判现在的发展
noe132
2022-04-25 23:09:23 +08:00
简单来说因为历史原因。
statumer
2022-04-25 23:09:56 +08:00
照理说 jsonp 这个东西也是不应该存在的,都是历史包袱
Chism
2022-04-25 23:17:59 +08:00
@sujin190
跨域请求 post 是先发个 get 试探,可以了再 post 吗?
honkew
2022-04-25 23:21:59 +08:00
需要拿到响应头,才能知道允不允许跨域啊
yin1999
2022-04-25 23:52:53 +08:00
@Chism 用的是 option 请求,而非 get
ch2
2022-04-26 00:04:40 +08:00
因为浏览器加载 js 跟 html 、css 、jpg 这些静态文件默认都是 GET ,一个网站在打开的一瞬会大量加载这些文件。往往加载这些文件的时候不会携带 cookie 等机密数据,所以就不预先 option 了,完全没必要。但是 fetch 、xhr 、ajax 等发送请求往往是带 cookie 的,这时候又不好单独鉴别是不是 fetch 跟 xhr 、ajax 发的 GET 请求,所以就只给 POST 预检 option ,不管 GET 了
ch2
2022-04-26 00:10:44 +08:00
@ch2 #10 跨域主要是防止你的网站盗用别人网站的凭据刷 api ,这样至少可以保证别人盗用你网站 cookie 的 POST 发都发不出去
Puteulanus
2022-04-26 00:17:20 +08:00
简单请求可以走其他方式发,比如 get 用图片的 src ,post 构造个表单直接 submit ,为了向上兼容不能拦这些,单独拦截异步请求发送的跨域请求就没有意义了
复杂请求因为无法用这种手段构造,所以拦截跨域是有意义的,但是全拦了大家又不方便,所以改用 option 询问一下服务器该不该拦
mxT52CRuqR6o5
2022-04-26 00:50:14 +08:00
因为有些接口有副作用,就比如转账接口,按照你的设计,虽然没有获取到转账结果,但转账请求发出去了
tyx1703
2022-04-26 09:18:51 +08:00
可能是因为简单请求的 http 报文小,发过去就算被拒绝了代价也比较小。非简单请求往往报文比较大,发过去再拒绝会造成资源浪费。而增加 options 预检,无论从时间还是空间维度,未增加过大负担,但带来的好处却显而易见。
lisongeee
2022-04-26 09:24:31 +08:00
@ch2

“跨域主要是防止你的网站盗用别人网站的凭据刷 api ,这样至少可以保证别人盗用你网站 cookie 的 POST 发都发不出去”

跨域中 简单请求 不需要预检,可以直接发出去,但是不一定收回来
DOLLOR
2022-04-26 09:25:05 +08:00
所以,干脆所有接口都用 post+json ,不用纠结什么“简单请求”,就没那么多事了🐶
weixiangzhe
2022-04-26 10:03:35 +08:00
现在 chrome 是 有一次 option 成功,之后就没有 option 了吧
lalalaqwer
2022-04-26 10:14:26 +08:00
@weixiangzhe 服务端可以通过 http 头控制 option 的作用时间的
fstar
2022-04-26 10:15:46 +08:00
@weixiangzhe 哦,这个是缓存。`Access-Control-Max-Age: 86400` 可以设置缓存时间。
bertonzh
2022-04-26 10:20:44 +08:00
是有一些设计问题,比如 request 的 content-type 为 application/json 需要发预检,而 www-form-urlencoded 却不需要。明明这两种只是序列化的方式不同而已。
另外如果自定义了 header ,也要发预检,这个也挺奇怪的。

要我设计,就应该 GET 都不发,POST PUT 等都发。

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

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

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

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

© 2021 V2EX