前言
我是一个java后端程序员,之前解决跨域都是在后端写一个过滤器,给HttpRequest的header添加都头信息。但是入职公司后线上服务器是通过配置nginx代理来解决跨域的,所以我再写个过滤器是多余。
现在都是前后端分离,为了更好的接口测试,让前端项目在我本地跑起来,研究了下前端角度(nginx和vue-cli)解决跨域的方法。由于不是专业前端,不对的请指正。
业务场景
后端: http://localhost:8080/project/
前端: http://localhost:8088/
受限于浏览器同源策略(跨域问题),无法在前端 http://localhost:8088/ 项目中请求后端http://localhost:8080/project/提供的接口。
两种跨域解决方法
解决原理
- 前端中,将要请求的真实接口 http://localhost:8080/project/ 变成 http://localhost:8080/api/
前端请求变为:
axios.post('/api/user/login', {params : params})
- nginx服务中,监听着 /api/ ,将 指向 /api/ 的请求,转发到指定的 proxy_pass 中。
- 转发的同时给请求头添加header信息。
Ngnix代理
- 编辑 %nginx_home%/conf/nginx.conf,在 http节点下, 增加一行代码 , include vhost/*.conf;; 就是引入自定义的配置文件
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
client_max_body_size 10m;
keepalive_timeout 0;
include vhost/*.conf;
}
- 在**%nginx_home%/conf/vhost/** 目录下, 新建自定义配置文件 xxx.conf;
- 编辑 xxx.conf,内容如下(具体配置及意义可百度);
server {
listen 8088;
server_name localhost,127.0.0.1;
index index.html;
# 这样配就是 root下的项目会启动在 http://localhost:8088/index.html
location / {
try_files $uri $uri/ /index.html;
# 前端项目打包编译后的目录
root E:/xxx/dist;
index login.html;
}
# 监听指向 api 的请求
location /api/ {
# 转到真实的后台接口地址
proxy_pass http://localhost:8080/manager/;
# 以下都是解决跨域需要添加的请求头信息
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
# 把cookie中的path部分从/api替换成/service
proxy_cookie_path /api /;
# 把cookie的path部分从localhost:8080替换成your.domain.name
proxy_cookie_domain localhost:80 http://localhost:8080;
}
}
- cmd中输入nginx -t,测试上述nginx配置是否配置成功;
- 输入start nginx 或者 nginx -s reload 启动或者重启nginx服务;
- 在浏览器中,http://localhost:8088/index.html , 查看前端项目是否成功启动,在F12查看是否成功请求后台接口。注意:即使成功的实现代理跨域,F12显示的请求地址仍然是 http://localhost:8088/api/ 。如果还是有跨域问题,请检查后台接口真实地址是否能访问,以及上述步骤是否哪里有不对。
vue-cli
- 前端中,将要请求的真实接口 http://localhost:8080/project/ 变成 http://localhost:8080/api/
前端请求变为:
axios.post('/api/user/login', {params : params})
- 在vue项目的config目录下的index.js中,修改proxyTable如下:
dev: {
env: require('./dev.env'),
port: 8088,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api': {
// 后台接口真实地址
target: 'http://localhost:8080/',
changeOrigin: true,
pathRewrite: {
// 将 步骤1 中设置的请求中的 /api/ 重写为 /project/
// 加上上面的target, 请求最终会变为 http://localhost:8080/project/
'^/api': 'project'
}
}
},
cssSourceMap: false
}
}
- npm run dev 将项目跑起来,如果在控制台中看到以下提示信息,则说明代理成功。
写在最后
我是一名Java后端,上述解决办法是自己在工作中站在后端角度在前端实践出来的解决方案,都是自己的理解,如有不准确,请不吝指正,谢谢。