问题描述
1、浏览器访问前端服务www.a.com,展示页面信息;(比如说这个前端资源部署在本地的node服务上,页面访问路径是http://localhost:8080/static/html/ajax-test.html)
2、访问的静态资源中,存在Ajax异步请求www.b.com访问动态数据;(比如用户在浏览器页面操作,提交一个post请求,访问一个第三方的开放OPEN接口服务http://yysxyy.com/app-s1/user)
3、很明显,这会存在跨域限制!除非第三方服务允许http://localhost:8080源做跨域访问。
4、第三方是别人的服务,我们没法设置。
5、我们本地用postman测试第三方的开放OPEN接口服务时可以正常访问的,没有跨域限制!postman不是浏览器,属于后台服务,后台服务跟后台服务进行访问,不存在跨域问题!
6、那么解决这个问题的点就在于,我们让浏览器请求我们自己的后台服务(比如Nginx),然后我们在我们自己的Nginx服务上进行跨域设置,然后我们用Nginx反向代理去访问第三方服务接口获取数据;
图解描述
跨域描述
image.png解决方案
image.png关键点!我们自己的Nginx服务的允许跨域设置
网上很多资料,基本无效!也许是Nginx版本问题,这里记录一下,我最终的设置方案
# server 配置
server {
listen 80;
server_name www.me.com; #我们自己的后台服务域名,如果是用ip访问我们自己的服务则这里设置为localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /open-b/ { #这里注意区分 设置的是专门用于第三方反向代理的请求url 匹配前缀
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'X-IPFSMAIN-TOKEN,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
proxy_pass http://www.b.com/; ##第三方域名,这里末尾加上/代表:不会带上open-b匹配路径进行跳转访问
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 5;
}
}
比如第三方接口url http://www.b.com/user;
我们自己的服务器(nginx)域名为www.me.com;
我们将我们的前端代码请求第三方接口url改为:http://www.me.com/open-b/user
验证
访问前端资源
image.pngSubmit按钮 js Ajax 访问其他服务接口
image.png使用postman测试http://47.102.204.135/app-s1/user(这里把它看成第三方接口)提交POST请求,可以获取正确响应没有任何问题
我的nginx配置——允许跨域、反向代理
image.png启动nginx服务
测试Submit访问
image.pngimage.png
成功跨域请求
image.png
值得注意的是,http://yysxyy.com/app-s1/user 被请求两次!
一次是OPTIONS,一次是POST!
OPTIONS用于校验资源的可访问性,POST是真正的目的请求!
如果nignx服务跟资源服务同属一台机器一个域名(也就是在第三方服务nginx设置允许跨域),那么不会存在OPTIONS这一次请求。
网友评论