Nginx的使用与反向代理解决跨域问题
一. 什么是跨域问题?
-
产生的原因
首先要知道,浏览器安全的基石是"同源政策"(same-origin policy),最初是由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
-
如果是非同源,限制范围:
(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM 无法获得。
(3) AJAX 请求不能发送。
-
同源策略举例
URL 说明 是否允许通信 / 是否同源 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不同域名 不允许 -
为什么前后端分离开发会遇到跨域问题?
例如后端服务运行在8080端口上,前端服务运行在63343端口上,由于端口号不同,前端在请求后端资源时会被游览器判定为跨域请求(非同源),请求会被拦截,且游览器控制台报错信息如下
Access To XMLHttpRequest at ... from orgin ... has been blocked by CORS policy ...
那么在开发时如何关闭游览器的同源策略?
Mac系统下开启Chrome游览器跨域请求方法
在终端执行以下命令即可,其中username为电脑用户名
1
open -n /Applications/Google\ Chrome.app/ --args --disable-web-security --user-data-dir=/Users/username/Documents/MyChromeDevUserData
Win系统下开启Chrome游览器跨域请求方法
-
如果是在部署项目至服务器时,可使用Nginx来解决
二. 使用Nginx反向代理解决跨域问题
-
原理举例:Nginx服务器监听指定端口号,将其指定URL请求代理至后端服务器,这样可以实现所有资源都在同一个端口号上进行访问,以下是配置方法
-
首先打开nginx.conf配置文件(若linux默认安装完不知道在哪可执行whereis nginx命令)
在http包裹下添加server配置
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
36
37server {
#监听端口号8085
listen 8085;
#配置服务请求名,若有多个用空格隔开,如 server_name www.baidu.com baidu.com test.baidu.com
server_name 39.106.196.52;
#编码
charset utf-8;
#access_log logs/host.access.log main;
location / {
#配置前端文件根目录
root /data/git/projects/blog/reportApplication;
#输入网址(server_name:port)后,默认的访问页面
index index.html index.htm;
}
#反向代理
location /api/ {
#后端服务器API地址
proxy_pass http://39.106.196.52:8080/reportDemo/;
#将cookie作用域转换至对应URL,若不设置此项会导致cookie session在反向代理中丢失问题
proxy_cookie_path /reportDemo /api;
proxy_cookie_path /reportDemo /;
tcp_nodelay on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}现在来分析下以上配置文件,首先这是个前后端分离项目:
后端服务所在地址: http://39.106.196.52:8080/reportDemo/
前端页面默认地址: http://39.106.196.52:8085/index.html
由于端口号不同,使用Nginx反向代理,将http://39.106.196.52:8085/api/代理到后端服务,那么前端请求后端时使用这个URL,就能在8085端口上访问到8080端口资源,给游览器造成这是同源的假象。
当然要注意cookie和session在反向代理中丢失的问题,曾在部署时遇到,最后发现要将cookie也同时代理过去,参照上面的设置即可。
三. 基于location配置多个前端项目
在上线测试时,如果为每个前端项目都配置一个域名或者端口,有点浪费资源。
因此我们希望通过IP访问加不同路径的形式来访问不同的前端项目,配置如下。
1 | # 这种方式配置的话,location / 目录是root,其他的要使用alias |
然后通过访问 IP 或 IP/web-b 就能分别访问两个不同的前端项目了。