您的位置:首页 > 运维架构 > Nginx

前后端分离:利用nginx的rewrite解决跨域问题

2016-08-14 00:00 906 查看
#引入

目前我们有连个站点www.a.com和api.b.com。
www.a.com里面有很多请求是发往api.b.com的,由于不在同一个domain域中,这就会产生跨域的问题,通常我们都是利用CORS来实现跨域的,也就是在服务端添加一下响应头:
1 Access-Control-Allow-Headers
2 Access-Control-Allow-Methods
3 Access-Control-Allow-Origin
4 Access-Control-Allow-Credentials
具体的配置可以百度或者google,当然解决跨域的方法还有诸如jsonp等等技术,当时今天我想说的却是利用nginx的url重写来实现。

#假设

假设www.a.com网站内有一个利用jquery发送的ajax请求,

$.ajax({
url:'api.b.com/api/getContent',
method:'POST',
data:略,
success:function(result){
略
}
})


如果我们没有做任何处理,在浏览器控制台我们就会得到一个跨域请求的异常,这儿我们就不多说,现在我们要做的是利用nginx来解决这个问题,我们先把这个ajax请求改一下:

//新的ajax请求
$.ajax({
url:'api/getContent',
method:'POST',
后面省略......
})


没错,就是把url给简写了,去掉了前面的请求地址,只保留了后面的请求url内容。
下面我们去配置nginx

#配置nginx.conf

在http节点下添加以下内容

server {
listen 80;
server_name www.a.com;
charset utf-8;

location /api {
rewrite ^.+api/?(.*)$ /$1 break;
proxy_pass http://api.b.com:8080/api/$1 }
location / {
proxy_pass http://www.a.com:8088/index.html; }
}

#重新加载nginx配置文件

nginx -s reload

#疑问

看出点什么了吗?当我们这个配置生效的情况下,前面那段新的ajax请求会发送到 www.a.com/api/getContent,当这个请求到达nginx时,会被location /api给匹配到,然后利用正则表达式进行匹配后面的内容也就是
rewrite ^.+api/?(.*)$

匹配到的内容表识为$1,然后用break停止
最后我们利用proxy_pass代理
http://api.b.com:8080/api/$1

也就是说最后我们的请求还是发送到了
api.b.com,所以我们的请求最后会被成功的响应。

那么为什么没有出现跨域的问题呢?

#总结

最后总结来自http://blog.jobbole.com/90975/

nginx是一个高性能的web服务器,常用作反向代理服务器。nginx作为反向代理服务器,就是把http请求转发到另一个或者一些服务器上。
通过把本地一个url前缀映射到要跨域访问的web服务器上,就可以实现跨域访问。
对于浏览器来说,访问的就是同源服务器上的一个url。而nginx通过检测url前缀,把http请求转发到后面真实的物理服务器。并通过rewrite命令把前缀再去掉。这样真实的服务器就可以正确处理请求,并且并不知道这个请求是来自代理服务器的。
简单说,nginx服务器欺骗了浏览器,让它认为这是同源调用,从而解决了浏览器的跨域问题。又通过重写url,欺骗了真实的服务器,让它以为这个http请求是直接来自与用户浏览器的。
这样,为了解决跨域问题,只需要动一下nginx配置文件即可。简单、强大、高效!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息