跨域资源共享CORS与jsonp

jsonpcorsXMLHttpRequest

Jmingzi createdAt at 2年前

目录

  • 跨域资源共享CORS
    • 概念
    • 什么情况下会触发CORS
    • CORS请求行为与分类
  • jsonp简要介绍
  • XMLHttpRequest简要介绍

跨域资源共享CORS

1.概念

说实话这个概念是今天第一次见到,可能这个概念属于前后端数据接口如何交互,并没有机会去接触了解这个场景,按理说也属于前端工程的一部分。

它的全称是cross-origin resource sharing,完全是按字面翻译过来的,好理解。

CORS是 HTML5 提供的标准跨域解决方案,我们所谈到的内容都是基于浏览器的,因为受限于浏览器的同源策略,所以才有这样的标准出现,离开浏览器,就不存在这些概念了吧。

2.什么情况下会触发CORS?

业务场景很普遍存在于多个域名下数据的交互,公司的业务不可能只有一个域名,例如公共的文件服务器就需要接受来自不同的也无方,此时就需要用到cors。

CORS的触发相对于ajax是无感知的,因为是浏览器帮你去做了一系列的事情(添加一些首部字段信息,来表明这是采用了跨域资源共享)。

CORS的实现需要服务器支持,只要服务器比如nginx设置了,浏览器就会在特定的情况下触发。

所以触发的条件即:该请求跨域了,且服务器支持跨域资源共享。

3.CORS请求行为与分类

跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。

简而言之就是cors会对服务器产生副作用的方法进行预检,即发送一个类型为options的请求,去探知服务器是否支持该请求域名的cors。

分为简单请求与复杂请求,因为在不同的分类下触发的条件不一致。

上面有提到“对服务器产生副作用的方法”才发起预检请求,简单请求就是包含了不会产生服务作用的方法。

3.1 简单请求(ajax)为同时满足以下条件:

  • 方法
    • GET
    • HEAD
    • POST
  • Content-Type 的值仅限于下列三者之一:
    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded

简单请求时的首部字段有2个最基本的特点:

请求报文中,会有origin字段表明请求来源:

origin: http://www.example.com

响应报文中,存在:

Access-Control-Allow-Origin: *

这样就完成了一个简单请求的跨域资源请求。

3.2 非简单请求

当请求满足下述任一条件时,即为非简单请求,非简单请求会先发送预检请求:

  • 方法
    • put
    • delete
    • options
    • trace
  • Content-Type 的值不属于下列之一
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain
  • 人为设置了如下首部字段以外的
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type (but note the additional requirements below)
    • DPR
    • Downlink
    • Save-Data
    • Viewport-Width
    • Width

只要满足以上任一条件都认为是非简单请求,最常见的是http请求时,将Content-Type设置为application/json

一个非简单请求的过程如下

3.3 跨域请求携带凭证 一般而言,对于跨域 XMLHttpRequest请求,浏览器不会发送身份凭证信息。如果要发送凭证信息,需要设置

xhr.withCredentials = true

在请求的时候设置该字段会带上cookie,如果服务器支持携带凭证,即服务器设置了

Access-Control-Allow-Credentials: true

简单请求携带凭证如图所示:

对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin 的值为“*”。因为cookie遵循同源策略,即协议,域名与端口相关。

以上参考:
HTTP访问控制(CORS)
跨域资源共享 CORS 详解

实践

git0

最后更新:2021年03月04日 14:54

鄂ICP备18011687号-1