专栏首页code秘密花园跨域的请求在服务端会不会真正执行?

跨域的请求在服务端会不会真正执行?

大家好,我是 ConardLi

上周在群里提了个问题,这是我平时面试经常会问到的一个问题,引起了大家非常激烈的讨论。

这个问题看似简单,但是其实这一个问题就足以看出大家对跨域的理解,如果平时只是了解了个概念, 那这个问题大概率不会答的那么好。

先揭晓一下答案,请求有的时候会被执行,有的时候不会执行。

那啥时候会执行,啥时候不会执行呢?其实这个问题主要要从以下几个方面去考虑:

  • 跨域究竟是谁的策略?
  • 在什么时机会拦截请求?
  • 究竟什么时候会发预检请求?
  • 如果有预检,请求什么时候会被真正执行?

跨域请求的拦截

有同学上来就答,一定不会执行的,请求在服务端就会被拦截!

这回答张口就来啊,先想想,服务端有什么责任和义务对跨域的请求做拦截呢?

首先我们俗称的跨域,也就是浏览器的 同源策略,直接看 MDN 的解释吧:

人家那么大个标题告诉你了,这很明显是个浏览器的策略啊,干服务端啥事呢?

如果服务端拦截,那每个每个 Server 都要专门要为浏览器实现一个拦截策略,这根本不现实。

另外,服务端就算是想拦截,也没法判断请求是否跨域,HTTP Reqeust 的所有 Header 都是可以被篡改的,它用什么去判断请求是否跨域呢?很明显服务端心有余而力不足啊!

在什么时候拦截

好了,知道服务端不会拦截了,有小朋友又跳出来抢答了:请求在浏览器发出去之前就被浏览器拦截了,请求根本发不出去!

这个问题先放放,大家可能都看过《解决跨域问题的XXX种方式》这样的文章,一般文章里都会告诉你用 CORS 去解决跨域。

大概的原理就是客户端会通过服务端返回的一些 Header 去判断该请求是否允许跨域:

比如,Access-Control-Allow-Origin 告诉客户端允许请求在哪些 Origin 下被发送,这些 Header 一般都是我们配在 Server 上的。

回到上面的问题,如果请求没发出去,这个 Header 是怎么被带回来的呢?浏览器又咋知道 Server 允许请求在哪些 Origin 下跨域发送呢?

所以,我们又明确了一个信息:请求一定是先发出去,在返回来的时候被浏览器拦截了,如果请求是有返回值的,会被浏览器隐藏掉。

预检请求

那这么说,请求既然被发出去了,服务端又不会拦截,所以一定会被执行喽?

那当然不是,我们再回来把 CORS 这张图放大来看:

我们发现,在发送真正的请求之前,浏览器会先发送一个 Preflight 请求,也就是我们常说的预检请求,它的方法为 OPTIONS

这也就是为什么有的时候我们明明只发了一个请求,在 Network 里却看到两个:

预检请求有一个很重要的作用就是 询问 服务端是不是允许这次请求,如果当前请求是个跨域的请求,你可以理解为:询问 服务端是不是允许请求在当前域下跨域发送。

当然,它还有其他的作用,比如 询问 服务端支持哪些 HTTP 方法。

预检的过程

当预检请求到达服务端时,服务端是不会真正执行这个请求的逻辑的,只会在这个请求上返回一些 HTTP Header,以此来告诉客户端是不是要发送真正的请求。

如果服务端告诉客户端,请求是允许被发送的,那真正的请求才会发出去。

比如:我在 a.com 这个 origin 下,发送了 conardli.top 这个域名的请求。

那么浏览器会先向 conardli.top 发送一个预检,预检请求不会真正执行这个域名的请求,而是返回了一些 CORS Header,比如 Access-Control-Allow-Origin: a.com

这时候浏览器发现, conardli.top 的请求是允许在 a.com 下发送的,才会真正发出请求。这时服务端才会真正执行请求接口的逻辑。

那么,所有的请求都会有预检吗?当然不是。

简单请求和复杂请求

预检请求虽然不会真正在服务端执行逻辑,但也是一个请求啊,考虑到服务端的开销,不是所有请求都会发送预检的。

一旦浏览器把请求判定为 简单请求,浏览器就不会发送预检了。

浏览器判定请求是否为简单请求要同时满足以下四个条件:

  • 使用下列方法之一:
    • GET
    • HEAD
    • POST
  • 只使用了如下的安全 Header,不得人为设置其他 Header
    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type 的值仅限于下列三者之一:
  • 请求中的任意 XMLHttpRequest 对象均没有注册任何事件监听器;XMLHttpRequest 对象可以使用 XMLHttpRequest.upload 属性访问。
  • 请求中没有使用 ReadableStream 对象。

所以,如果你发送的是一个简单请求,这个请求不管是不是会受到跨域的限制,只要发出去了,一定会在服务端被执行,浏览器只是隐藏了返回值而已。

现在,一切都清晰了吧 ...

总结

最后来总结下要点:

  • 简单请求:不管是否跨域,只要发出去了,一定会到达服务端并被执行,浏览器只会隐藏返回值
  • 复杂请求:先发预检,预检不会真正执行业务逻辑,预检通过后才会发送真正请求并在服务端被执行

如果你有任何想法,欢迎在留言区和我留言,如果这篇文章帮助到了你,欢迎点赞、在看和关注。你的点赞、在看和关注是对我最大的支持!

好奇,你答对了吗?

文章分享自微信公众号:
code秘密花园

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!

作者:ConardLi
原始发表时间:2022-04-07
如有侵权,请联系 cloudcommunity@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • 在ASP.NET 5应用程序中的跨域请求功能详解什么是“同域”添加CORS包在应用程序中配置CORSCORS策略选项跨域请求中的凭据设置先行请求的过期时间CORS是怎么样工作的先行请求

    浏览器安全阻止了一个网页中向另外一个域提交请求,这个限制叫做同域策咯(same-origin policy),这组织了一个恶意网站从另外一个网站读取敏感数据,但...

    小白哥哥
  • Javascript跨域后台设置拦截

    子域名之间互相访问需要跨域 结论放在开头: 服务端必须设置允许跨域 客户端带cookie需要设置withCredentials 无论服务端是否允许跨域,该req...

    Ryan-Miao
  • AJAX 与跨域通信(二):跨域解决方案

    本篇讲解常见的几种跨域方案:JSONP、CORS、图像Ping、document.domain、window.name。

    Chor
  • Ajax 跨域问题及其解决方案

    主流的前后端分离模式下,当前端调用后台接口时,由于是在非同一个域下的请求,从而会引发浏览器的自我安全保护机制,最终结果是接口成功请求并响应,但前端不能正常处理该...

    佛系贲八拉
  • Ajax跨域问题及其解决方案

    主流的前后端分离模式下,当前端调用后台接口时,由于是在非同一个域下的请求,从而会引发浏览器的自我安全保护机制,最终结果是接口成功请求并响应,但前端不能正常处理该...

    happyJared
  • Nginx 轻松搞定跨域问题!

    点击关注公众号,Java干货及时送达 来源:酒香逢 地址:www.cnblogs.com/fnz0/p/15803011.html 当你遇到跨域问题,不要立...

    Java技术栈
  • HTTP跨域详解和解决方式

    那么究竟什么是跨域,跨域又是怎么产生的,以及跨域请求的问题需要怎么解决。我们一起来了解一下这些知识。

    仙士可
  • 前端-不要再问跨域的问题了

    跨域这两个字就像一块狗皮膏药一样黏在每一个前端开发者身上,无论你在工作上或者面试中无可避免会遇到这个问题。为了应付面试,我每次都随便背几个方案,也不知道为什么要...

    grain先森
  • 6种解决跨域方案,今天全告诉你了

    跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制。

    公众号 IT老哥
  • 腾讯一面:CORS为什么能保障安全?为什么只对复杂请求做预检?

    大家好,我是年年!提起CORS,大部分的文章都在写什么是简单请求、什么是复杂请求,复杂请求预检的流程又是怎样。

    用户9899350
  • web跨域及cookie相关知识总结

      之前对于跨域相关的知识一致都很零碎,正好现在的代码中用到了跨域相关的,现在来对这些知识做一个汇总整理,方便自己查看,说不定也可能对你有所帮助。

    用户2038589
  • 跨源资源共享(CORS)

    https://www.cnblogs.com/poloyy/p/15345184.html

    小菠萝测试笔记
  • TSINGSEE青犀视频流媒体平台为什么会存在跨域问题?

    在EasyNVR、EasyGBS、EasyDSS这一类视频平台中,经常会碰到用户问我们跨域相关的问题,在视频流的传输上,某些项目需要将视频流嵌入第三方平台或者a...

    TSINGSEE青犀视频
  • 如何处理跨域时的 OPTIONS 请求?

    最近在公司项目中与后端联调时遇到了一个很奇怪的问题,前端发出的 DELETE 方法的 Ajax 请求传到服务端就变成了 OPTIONS 请求。由于服务端没有针对...

    逆葵
  • 跨域(CORS)产生原因分析与解决方案,这一次彻底搞懂它

    Cross-origin Resource Sharing 中文名称 “跨域资源共享” 简称 “CORS”,它突破了一个请求在浏览器发出只能在同源的情况下向服务...

    五月君
  • CORS跨域资源共享(一):模拟跨域请求以及结果分析,理解同源策略【享学Spring MVC】

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    YourBatman
  • 同源策略浅析

    一个重要原因就是对cookie的保护,cookie 中存着sessionID 。如果已经登录网站,同时又去了任意其他网站,该网站有恶意JS代码。...

    随心助手

扫码关注腾讯云开发者

领取腾讯云代金券