用nginx的反向代理机制解决前端跨域问题

什么是跨域以及产生原因

跨域是指a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,或是a页面为ip地址,b页面为域名地址,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。

跨域情况如下:

url url 说明 是否跨域
http://www.cnblogs.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 主域相同,子域不同 是(cookie不可访问)
http://www.a.com/a.js http://a.com/b.js 同一域名,不同二级域名(同上)

跨域的常见解决方法

目前来讲没有不依靠服务器端来跨域请求资源的技术

1.jsonp 需要目标服务器配合一个callback函数。

2.window.name+iframe 需要目标服务器响应window.name。

3.window.location.hash+iframe 同样需要目标服务器作处理。

4.html5的 postMessage+ifrme 这个也是需要目标服务器或者说是目标页面写一个postMessage,主要侧重于前端通讯。

5.CORS需要服务器设置header :Access-Control-Allow-Origin。

6.nginx反向代理

这个方法一般很少有人提及,但是他可以不用目标服务器配合,不过需要你搭建一个中转nginx服务器,用于转发请求。

nginx反向代理解决跨域

上面已经说到,禁止跨域问题其实是浏览器的一种安全行为,而现在的大多数解决方案都是用标签可以跨域访问的这个漏洞或者是技巧去完成,但都少不了目标服务器做相应的改变,而我最近遇到了一个需求是,目标服务器不能给予我一个header,更不可以改变代码返回个script,所以前5种方案都被我否决掉。最后因为我的网站是我自己的主机,所以我决定搭建一个nginx并把相应代码部署在它的下面,由页面请求本域名的一个地址,转由nginx代理处理后返回结果给页面,而且这一切都是同步的。

关于nginx的一些

基本配置和安装

请看我的另一篇博客,下面直接讲解如何配置一个反向代理。

首先找到nginx.conf或者nginx.conf.default 或者是default里面的这部份

image.png

其中server代表启动的一个服务,location 是一个定位规则。

location /{   #所有以/开头的地址,实际上是所有请求
root  html     #去请求../html文件夹里的文件,其中..的路径在nginx里面有定义,安装的时候会有默认路径,详见另一篇博客
index  index.html index.htm  #首页响应地址
}

从上面可以看出location是nginx用来路由的入口,所以我们接下来要在location里面完成我们的反向代理。

假如我们我们是www.a.com/html/msg.html 想请求www.b.com/api/?method=1&para=2

我们的ajax:

var url = 'http://www.b.com/api/msg?method=1&para=2';
<br>$.ajax({
type: "GET",
url:url,
success: function(res){..},
....
})

上面的请求必然会遇到跨域问题,这时我们需要修改一下我们的请求url,让请求发在nginx的一个url下。

var url = 'http://www.b.com/api/msg?method=1&para=2';
var proxyurl = 'msg?method=1&para=2';
//假如实际地址是 www.c.com/proxy/html/api/msg?method=1&para=2; www.c.com是nginx主机地址
 $.ajax({
type: "GET",
url:proxyurl,
success: function(res){..},
....
})  

再在刚才的路径中匹配到这个请求,我们在location下面再添加一个location。

location ^~/proxy/html/{
rewrite ^/proxy/html/(.*)$ /$1 break;
proxy_pass http://www.b.com/;
}

以下做一个解释:

1.'^~ /proxy/html/ '

就像上面说的一样是一个匹配规则,用于拦截请求,匹配任何以 /proxy/html/开头的地址,匹配符合以后,停止往下搜索正则。

2.rewrite ^/proxy/html/(.*)$ /$1 break;

代表重写拦截进来的请求,并且只能对域名后边的除去传递的参数外的字符串起作用,例如www.c.com/proxy/html/api/msg?method=1&para=2重写。只对/proxy/html/api/msg重写。

rewrite后面的参数是一个简单的正则 ^/proxy/html/(.*)$ ,$1代表正则中的第一个(),$2代表第二个()的值,以此类推。

break代表匹配一个之后停止匹配。

3.proxy_pass

既是把请求代理到其他主机,其中 http://www.b.com/ 写法和 http://www.b.com写法的区别如下:

不带/

location /html/
{
  proxy_pass http://b.com:8300; 
}

带/

location /html/ 
{ 
    proxy_pass http://b.com:8300/; 
}

上面两种配置,区别只在于proxy_pass转发的路径后是否带 “/”。

针对情况1,如果访问url = http://server/html/test.jsp,则被nginx代理后,请求路径会便问http://proxy_pass/html/test.jsp,将test/ 作为根路径,请求test/路径下的资源。

针对情况2,如果访问url = http://server/html/test.jsp,则被nginx代理后,请求路径会变为 http://proxy_pass/test.jsp,直接访问server的根资源。

修改配置后重启nginx代理就成功了。

nginx的实际原理就是配置一个代理路径替换实际的访问路径,使得浏览器认为访问的资源都是属于相同协议,域名和端口的,而实际访问的并不是代理路径,而是通过代理路径找到实际路径进行访问。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容