JavaScript 中的 HTTP 跨域请求

 

自从我接触前端以来,接手的项目里面很大部分都是前后端分离的,后端只提供接口,前端根据后端接口渲染出实际页面。个人觉得这是一个挺好的模式,前后端各自负责各自的模块,分工明确,而且也给前端更大的发挥空间。

与以前套模板的模式不同,前后端分离以后,前端跟后端的沟通绝大部分都是通过前端主动向后端发起请求来完成的。而前端的请求又绝大部分是由 Ajax 构成的,Ajax 是一种非常方便的获取数据的方式。但是,一旦 Ajax 碰上跨域,那么问题就会麻烦很多。这篇文章主要梳理了我在项目开发里面碰到的一些关于跨域请求的问题,当然也会有一些关于跨域请求的一些背景知识。PS:文末有个小彩蛋哦:smile:

严格来说,跨域请求并不仅仅只是 Ajax 的跨域请求,而是对于一个页面来说,只要它请求了其他域名的资源了,那么这个过程就属于跨域请求了。比如,一个带有其他域名的 src 的 <img>标签,以及页面中引入的其他第三方的 CSS 样式等。

对于 img 以及 CSS 而言,跨域请求本身并没有更多的安全问题,因为这些请求都属于只读请求,并不会对源资源造成副作用。而如果跨域请求是从脚本里面发出去的,由于脚本具有高度灵活性,浏览器出于安全考虑,会根据同源策略来限制它的功能,使得正常情况下,脚本只能请求同源的资源。如果页面确实需要通过脚本请求其他网站的资源,那么就应当在跨域资源共享(CORS)的机制下工作。

等等同学,什么叫做同源策略?

同源策略(Same-origin policy)

对于两个页面(资源)而言,只要他们满足以下三个条件则称他们符合同源策略:

  1. 协议相同

  2. 端口相同

  3. 域名相同

另外, about:blank 和 javascript: 继承加载这些资源的页面的 origin。 data: 的资源不同,自身会拥有一个空的安全的上下文。

另外,子域可以通过JS 设置 document.domain 来通过同源策略。如:

在子域 http://a.example.com/test.html 的页面中,通过 JS 设置 document.domain='example.com' ,则当前页面与 http://example.com/page.html 符合同源策略。

简单的说,对于页面 http://www.example.com/page1.html 来说,以下页面与它都不符合同源策略,脚本无法直接请求这些资源:

  • https://www.example.com/page1.html : 协议不同

  • http://www.example.com:81/page1.html : 端口不同

  • http://another.example.com/page1.html : 域名不同

那么,什么又是 CORS 呢?

CORS(Cross-Origin Resource Sharing)

CORS 本质上是规定了一系列的 HTTP 头来作为判断脚本是否能够实现跨域请求。在了解这些请求头之前,先来看看跨域请求有哪些类型。

通过脚本来发出请求有两种方式,一种是通过创建 XMLHttpRequest 的方式来发出请求,另外一种是通过 fetch API 来实现请求。

一般来说,跨域请求可以大致分为两种,其中一种称之为简单的请求,其符合以下条件:

  • 请求的方法是 GET 、 POST 、 HEAD 其中之一。

  • 除了浏览器自动带上的请求头(如 ConnectionUser-Agent 等)之外,只允许下面几种请求:头

    • Accept

    • Accept-Language

    • Content-Language

    • Content-Type

  • Content-Type 请求头的值只能是 application/x-www-form-urlencoded 、 multipart/form-data 、 text/plain 其中之一。

反之,如果有违背上面三条规则中的任意一条,那么即不是简单的跨域请求。非简单的跨域请求相对于简单的跨域请求来说区别在于,请求在发出去之前,浏览器会先发送一个 preflighted 请求,用来向服务器端确认接下来要进行的请求是否是被允许的。

关键字:

50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信