跨域解决方案

前后端分离的思想越来越普及,要做好前后端分离,那就要先跨好域~

我们在前后端分离的时候,后端会有自己的服务器,这个大家都知晓。在大前端的潮流下,前端往往也会有自己的服务器,这样各司其职,提升开发效率,但随之也带来了跨域的问题。

什么是跨域

跨域顾名思义,就是跨出了同一个域。我们可以看以下的示例帮助我们更好理解:

http://www.a.com/a.js
http://www.a.com/b.js 同一域名下 允许通信

http://www.a.com/lab/a.js
http://www.a.com/script/b.js 同一域名下不同文件夹 允许通信

http://www.a.com:8000/a.js
http://www.a.com/b.js 同一域名,不同端口 不允许通信

http://www.a.com/a.js
https://www.a.com/b.js 同一域名,不同协议 不允许通信

http://www.a.com/a.js
http://70.32.92.74/b.js 域名和域名对应ip 不允许通信

http://www.a.com/a.js
http://script.a.com/b.js 主域相同,子域不同 不允许通信

http://www.a.com/a.js
http://a.com/b.js 同一域名,不同二级域名(同上)不允许通信(cookie这种情况下也不允许访问)

http://www.cnblogs.com/a.js
http://www.a.com/b.js 不同域名 不允许通信

跨域的方案

那出现了问题,我们就结束问题喽,跨域的方式挺多种的。比如jsonp就可以解决,但jsonp有它的局限性,这里就不介绍它了,因为它不是主角~ 这次主要的解决方案是通过nginx来实现CORS。

CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

关于CORS可以看这篇文章 跨域资源共享 CORS 详解

接下来我们就进入正题,如何利用nginx实现跨域。

安装nginx

首先肯定要先有nginx,无论是Linux还是windons,一搜就有拉,就不重复了,就当都安装好了nginx。

配置nginx

这里是重点,我贴上我自己的nginx配置,供大家参考,亲测有效,屡试不爽。

文件 nginx_cors:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS,PUT,DELETE';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'authorization,Authorization,keep-alive,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 200;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS,PUT,DELETE';
add_header 'Access-Control-Allow-Headers' 'authorization,Authorization,keep-alive,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS,PUT,DELETE';
add_header 'Access-Control-Allow-Headers' 'authorization,Authorization,keep-alive,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With';
}
if ($request_method = 'PUT') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS,PUT,DELETE';
add_header 'Access-Control-Allow-Headers' 'authorization,Authorization,keep-alive,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With';
}
if ($request_method = 'DELETE') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS,PUT,DELETE';
add_header 'Access-Control-Allow-Headers' 'authorization,Authorization,keep-alive,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With';
}

在nginx的配置文件引入,这里的路径换成自己的。

1
2
3
location / {
include /etc/nginx/conf.d/nginx_cors;
}

重启nginx,就大功告成拉。

最后补充一点点东西,用vue.js发送请求 和 直接用jQuery发送请求两者是有差异的。

jQuery走的是简单请求

只使用 GET, HEAD 或者 POST 请求方法。如果使用 POST 向服务器端传送数据,则数据类型(Content-Type)只能是 application/x-www-form-urlencoded, multipart/form-data 或 text/plain中的一种。
不会使用自定义请求头(类似于 X-Modified 这种)

而vue.js 走的是复杂请求,资料上这样描述的

跨源资源共享标准通过新增一系列 HTTP 头,让服务器能声明那些来源可以通过浏览器访问该服务器上的资源。另外,对那些会对服务器数据造成破坏性影响的 HTTP 请求方法(特别是 GET 以外的 HTTP 方法,或者搭配某些MIME类型的POST请求),标准强烈要求浏览器必须先以 OPTIONS 请求方式发送一个预请求(preflight request),从而获知服务器端对跨源请求所支持 HTTP 方法。 在确认服务器允许该跨源请求的情况下,以实际的 HTTP 请求方法发送那个真正的请求。服务器端也可以通知客户端,是不是需要随同请求一起发送信用信息(包括 Cookies 和 HTTP 认证相关数据)。

完。^.^

更多精彩 戳我