前后端 跨域请求

本文将介绍跨域请求的解决方法。

一、同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。

可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

1. 同源

同源是指”协议+域名+端口”三者相同。

2. 同源策略

一个域下的 JavaScript,不允许读取另一个域下的内容。

当 JavaScript 被执行时,浏览器会首先判断脚本和页面是否同源,仅当同源时,JavaScript 才会被执行。

同源策略是浏览器的安全功能,确保一个应用中的资源仅能被本应用所访问,帮助阻隔恶意攻击。

二、跨域问题

1. 为什么要跨域?

跨域问题是同源策略所导致的。

由于同源策略,浏览器只允许请求当前域的资源。如果希望获取其它域的资源,便需要跨域。

2. 跨域的实现方法

  • CORS
  • 服务器代理:用自身服务器作为中转服务器,通过请求自身服务器间接获取目标资源
  • JSONP

三、JSONP

1. 什么是 JSONP?

JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务器改造非常小。

2. 实现基础

浏览器并不会对 script 做跨域限制。

否则将无法引入 CDN 上的 js 文件

同样的 <img>、<iframe> 也拥有跨域能力

3. 实现思路

在客户端,

  • 写好跨域资源处理函数
  • 通过 <scrpt> 的向跨域服务器请求 JavaScript 代码

在跨域服务器端,

  • 动态生成 JavaScript 代码,代码中应包含:
    • 数据
    • 调用客户端上的跨域资源处理函数
  • 将 JavaScript 代码发送给客户端

通过这样的方式,就能请求跨域资源,并在请求完成之后对资源进行处理。

网络请求完成之前:

1
2
3
4
5
6
7
<script>
function 函数名() {
···
}
</script>

<script src="请求路径"></script>

网络请求完成之后:

1
2
3
4
5
6
7
8
9
10
<script>
function 函数名() {
···
}
</script>

<script>
···数据···
函数名();
</script>

4. 缺点

仅能支持 get 请求(因为只能通过链接向后端请求数据)

四、CORS

1. 什么是 CORS ?

  • CORS 是一种 W3C 标准,其全称是 跨域资源共享 ,它允许浏览器向跨域服务器发送请求
  • CORS 需要浏览器和服务器同时支持
  • 发出 CORS 请求和发出 AJAX 请求,对于程序员而言是无感的,因为发出 CORS 请求所需要做的事情将由浏览器自动完成

2. 两种请求

浏览器将 CORS 请求分为两类:

  • 简单请求
  • 非简单请求

其中,简单请求应该满足:

  • 请求方法为 HEAD、GET 或 POST
  • Header 中不超出以下字段:
    • Accept
    • Accept-Language
    • Content-Language
    • Last-Event-ID
    • Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain

3. 简单请求的处理

(1) 请求

如果浏览器判断得到请求是简单 CORS 请求,它会自动在头信息中添加 Origin 字段。

Origin 字段说明请求来自哪个源。

服务器将根据 Origin 字段以及跨域配置,决定是否同意来自该域的请求。

(2) 响应

  • 如果服务器不同意来自该域的请求,则服务器将会返回一个正常的 HTTP 响应(其错误无法通过响应状态码判断),但响应头中将不会包含 Access-Control-Xxx-Xxx 等信息

  • 如果服务器同意来自该域的请求,则服务器将会返回一个正常的 HTTP 响应,响应中携带返回信息,且响应头中将包含 Access-Control-Xxx-Xxx 等信息

4. 非简单请求的处理

  • 对于非简单请求,往往会在正式通信之前增加一次 “预检” 请求,其请求方法为 Options,请求头中将携带对正式请求的描述信息
  • 当且仅当 “预检” 请求被正确响应后,正式请求才会发出

参考