跨域资源共享 CORS

跨域资源共享 CORS

什么是CORS

在项目开发过程中,经常碰到跨域问题,同时也就不可避免的接触到cors

cors 是由 W3C 定义的,它的全称是------跨域资源共享 。但笔者第一次听到这个名称时仍然觉得云里雾里,并不知道他的具体是什么,笔者认为,实际上我们平常提到的cors有两种不同的含义,我们不妨为它加上一些定语,让它读起来更加易懂:

  1. 跨域资源共享问题

这里的cors指:

"受cors规范限制的浏览器 向未满足cors规范要求的服务器发送了跨域请求,因而无法得到响应。"

这样一种问题。

简单来说,就是当满足cors规范的浏览器向不满足cors规范的服务器发送请求时会受到限制,会拒绝掉服务器返回的响应,这种无法得到响应的情况被称为cors情况。

  1. 跨域资源共享协议跨域资源共享规范

这里笔者斗胆为该语境的cors给出以下定义:

cors规范是用来解决浏览器与服务器之间跨域问题的 http 请求规范。

再通俗易懂一点, 在这种语境下的cors规定了为了浏览器安全,其在进行跨域请求时受到什么限制,服务器在响应跨域请求时应该怎么响应。

什么时候会遇到CORS情况?

既然被称为跨域资源共享情况,肯定是在跨域过程中才会使用到,那么首先需要了解跨域的具体定义。

同源策略与跨域

同源

我们都知道一个 URL,例如https://www.example.com:80/helloworld?a=1?b=2#title分为如下几部分:

  • https ------ 协议
  • www.example.com ------ 域名
  • 80 ------ 端口
  • /helloworld?a=1?b=2#title ------ 资源路径、参数等

当两个 URL 的协议、域名、端口完全相同时,我们称这两个 URL同源

跨域

当两个 URL 不同源时却发起 http 请求时,我们称之为跨域,例如:

  • https://www.example.com:80https://www.example.com:81发送请求时,发生了跨域。因为端口号不同。
  • https://www.example1.com:80https://www.example2.com:80发送请求时,发生了跨域。因为域名不同。
  • http://www.example.com:80https://www.example.com:80发送请求时,发生了跨域,因为协议不同。

CORS情况与跨域的不同

我相信有很多人认为跨域与cors情况是相同的,但笔者给出一个不同的观点,即cors情况与跨域有如下不同:

概念不同

跨域是一个广义上的概念,是针对所有URL提出的,即理论上可以对任意两个URL进行判断是否跨域。 而cors情况是一个针对浏览器安全提出的情况,因此只涉及到浏览器与服务器之间的URL判断,即只有浏览器与服务器的URL之间会出现cors情况,服务器与服务器之间的URL不会出现cors情况。

表现不同

由概念不同延伸,当真正发生跨域时,并不一定会出现cors情况。 例如:当 服务器 A 向 服务器 B 发送请求时(显然 服务器 A 与 服务器 B 的域名 并不相同),此次请求是跨域请求,但却并不是cors情况。 因此笔者在上方给出的定义中特别强调了,不论是cors情况还是cors规范,一定是浏览器与服务器之间发生的故事。

综上所述

只有在浏览器服务器 发送跨域请求 时,才会发生cors情况,此时的解决方案正是让服务器满足cors规范。

CORS的具体规范内容

在理解了cors究竟是什么之后,再来看看cors的具体规范内容。 前文已经提到过了,满足cors规范的浏览器会受到一些限制,当服务器不满足cors规范时,就无法实现浏览器与服务器的http请求,接下来分别分析:

CORS的预检机制

cors为服务器提供了一种机制,即: cors规范将 http 请求分为两种,分别是简单请求与复杂请求(该说法在最新的规范中已经弃用,此处只是将两种请求做一个区分)。 如果想知道cors规范具体如何区分简单请求与复杂请求,请前往MDN

简单请求

  1. 简单请求不触发预检机制,将直接发送完整http请求。
  2. 服务器端正常响应请求。
  3. 浏览器端查看服务器端的响应头是否满足cors规范,若不满足规范则拒绝接收数据。

复杂请求

  1. 当浏览器向服务器发送跨域请求时,会先进行一次预检,发送一个option方法的http请求。
  2. 服务器端将对该请求的请求头进行判断,若该请求头不满足服务器端的规定,则不再发送携带数据的真实请求。
  3. 浏览器端接收到错误响应,报错。

CORS对服务器端的规范

cors为服务器端对于浏览器端请求的响应提供了一系列响应头:

  • Access-Control-Allow-Origin 规定在接受跨源请求时,允许该请求来自何处。
  • Access-Control-Expose-Headers 规定在接受跨源访问时,浏览器端能拿到的额外响应头。
  • Access-Control-Allow-Methods规定在接受跨源访问时,允许浏览器发送的http方法。

等等.....

cors为服务器提供了许多可设置的响应头,此处不过多讨论具体代码,仅探讨原理,想了解可以到MDN学习。 (方便我以后再水一篇博客)

浏览器端受到的限制

上文提到了cors为服务器提供的响应头,而cors对浏览器端的限制是:

  1. 浏览器端向跨域服务器发送http请求时,会携带origin等头,用来表明请求来自何处。
  2. 只有当服务器返回的响应包含正确的响应头才能成功接收到数据。
  3. 当服务器端返回的响应未包含正确响应头时,浏览器会主动拒绝接收该响应。

cors同样为浏览器端提供了一系列请求头:

  • Origin写明了发送跨域请求时,请求来自何处,即不包含路径等信息的源站 URL。
  • Access-Control-Request-Method用于将实际请求所使用的http方法告诉服务器。
  • Access-Control-Request-Headers用于将实际请求所携带的标头字段告诉服务器。

同样,具体见mdn

例子

当浏览器http://127.0.0.1:5678向跨域服务器http://127.0.0.1:5700发送http请求时, 其请求头将自动添加一项origin: 'http://127.0.0.1:5678', 而服务器端未设置响应头Access-Control-Allow-Origin 或设置为Access-Control-Allow-Origin:http://127.0.0.1:8080, 则浏览器将拒绝接收来自服务器的响应。

总结

cors是前端开发中经常碰到的情况,当然解决方案也并不只是使服务器端配置满足cors这一种,其他解决方案此处不讨论,未来总结后会把链接贴在这里。

相关推荐
秦jh_1 小时前
【Linux】多线程(概念,控制)
linux·运维·前端
蜗牛快跑2131 小时前
面向对象编程 vs 函数式编程
前端·函数式编程·面向对象编程
Dread_lxy1 小时前
vue 依赖注入(Provide、Inject )和混入(mixins)
前端·javascript·vue.js
涔溪2 小时前
Ecmascript(ES)标准
前端·elasticsearch·ecmascript
榴莲千丞2 小时前
第8章利用CSS制作导航菜单
前端·css
奔跑草-2 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
羡与2 小时前
echarts-gl 3D柱状图配置
前端·javascript·echarts
guokanglun2 小时前
CSS样式实现3D效果
前端·css·3d
咔咔库奇2 小时前
ES6进阶知识一
前端·ecmascript·es6
渗透测试老鸟-九青3 小时前
通过投毒Bingbot索引挖掘必应中的存储型XSS
服务器·前端·javascript·安全·web安全·缓存·xss