浏览器不求别人,用nginx反向代理就能搞跨域
Posted 神仙朱
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浏览器不求别人,用nginx反向代理就能搞跨域相关的知识,希望对你有一定的参考价值。
面试遇坑
面试官: 你知道跨域有什么解决办法吗?
神仙朱:JSONP 或者 后端修改相应头部 Accept-Control-Allow-Origin ??
面试官:看你还用过 nginx 啊,不知道 nginx 可以反向代理解决跨域吗 ?
我心想还有这种操作 ??于是我很自信地回答他我不知道
素来我是遇到问题一定要解决的,没有什么东西可以一直困扰我。
于是上网查了大量资料(一两篇文章),然后就尝试配置了一下 nginx ,最后真的解决了!!
现在我就来做一份自己的总结!
关键词
先来把几个关键知识点理一下
跨域
浏览器的同源策略 导致跨域! 注意是浏览器,只有在浏览器才存在有跨域。
也就是说 服务器上不存在 跨域 的说法。
所以才存在今天使用 服务器代理解决跨域的方法。
跨域的请求过程
跨域请求一般浏览器是可以发送跨域请求的,只是响应被拦截了。
而 chrome 下会先发一个 options 请求去询问浏览器是否可以跨域,并且对这个请求结果进行缓存。
如果 options 请求得到 跨域不允许,那么下一次跨域的时候不会再发送新的 options 请求 ,而是直接报跨域错误。
代理
正向代理
正向代理是隐藏客户端,服务器不知道真正的请求人。
比如你想访问某个网站,但是没有直接去访问,而是通过一个 代理服务器去访问 这个网站,利用代理服务器帮你发送请求,再把请求返回的信息转发给你。
上面的过程中,那个网站的服务器根本不知道到底是谁访问我。那么就达到了隐藏客户端的目的,这就是正向代理。
应用
科学上网:在国外部署代理服务器,通过这个代理服务器 实现代发请求,就可以科学上网
反向代理
反向代理 是隐藏服务器。客户端不知道真正的服务人。因为服务器会自动分配服务你的服务器,而你不知道真正给你提供服务的是谁。
比如我们访问淘宝,淘宝的服务器有很多。当我们访问淘宝的时候,淘宝服务器会将我们的请求转发给其他服务器。这时,淘宝服务器实现的功能就是 反向代理。
nginx 反向代理解决跨域
配置 window nginx 来测试一下
安装 nginx
访问官网下载:
http://nginx.org/en/download.html选择 window 版本
比如 nginx/Windows-1.12.2下载成功,解压到某个文件夹,比如 D:/nginx
ok
启动 nginx
Ctrl+R 打开 CMD
进入到刚刚解压的文件夹
运行命令 ./nginx.exe
正常情况下,启动成功没有任何提示
配置 nginx
进入到解压的文件夹
比如D:/nginx进入 conf 文件夹,看到nginx.conf 就是配置文件,打开它,
修改端口
原来nginx 的端口是80,不过window 下 80端口可能被 System 占用了,所以我们换一个端口 ,比如是 8089
配置服务器请求匹配路径
在 (location / )后面加上另一个自定义路径配置
这里我的路径是 /ho/ 也就是说如果我发送的请求中带有 ho ,那么就会匹配成功。
比如 发送请求是
http://localhost:8089/ho/xxxx
里面包含 ho,所以匹配成功
1 |
|
下面照着上面的配置来详细说明一下
rewrite
举例
假设我们现在要在本地网页localhost通过 ajax 访问一个接口
http://jingyan.baidu.com/asyncreq/log?method=getLog&likeNum=39010735291423126980&type1423=6557184
一般情况下,这是会跨域的
而我们的目的就是想可以通过本地网页成功访问服务器接口!!
所以先在本地构建一个接口,通过这个接口去转发到真正的接口上去!!!!
http://localhost:8089/ho/asyncreq/log?method=getLog&likeNum=39010735291423126980&type1423=6557184
回到nginx配置上来,看到 rewrite 设置为 ^.+ho/(.*)$ /$1 break
不急,我们先尝试使用上面的正则去匹配URL测试最后会得到什么
1 |
/^.+ho\/(.*)$/.exec("http://localhost:8089/ho/asyncreq/log?method=getLog&likeNum=39010735291423126980&type1423=6557184") |
看到 rewrite 还有一个 $1,就是取数组的第二个的意思
那么得到可以得到
/asyncreq/log?method=getLog&likeNum=39010735291423126980&type1423=6557184
就是这个没错了,我们就要这个
proxy_pass
协议可以是 http 或者 https
既然拿到了 正确的api路径,那么我们现在要做的就是确定要真正发送请求的服务器的域名
比如是 https://jingyan.baidu.com
所以设置 proxy_pass 为 https://jingyan.baidu.com
那么最后我们发出去的请求就是
http://jingyan.baidu.com/asyncreq/log?method=getLog&likeNum=39010735291423126980&type1423=6557184
重启nginx
我们已经修改了配置文件了,现在要做的就是重启nginx
运行命令 nginx -s reload
到这一步,nginx 相关的我们都做完啦,下面就写一个页面测试一下接口反向代理是否成功
写测试页面
新建一个 nginx.html 文件放在 nginx解压目录下的 html 中
1 |
<!DOCTYPE html> |
然后打开这个页面,打开链接 http://localhost:8089/nginx.html
最后我们可以在控制台看到请求返回的信息
我还能说什么?不就是成功了喽
结尾
在做项目的时候,调用后端项目的时候总是会涉及到跨域。
而JSONP需要后端配合根本就是很少用,要不然也只能去求后端爸爸设置一下响应头部
现在,我们不用求别人了!!靠自己,就能解决跨域问题!!!
PS:感觉文章排版还是乱乱的
以上是关于浏览器不求别人,用nginx反向代理就能搞跨域的主要内容,如果未能解决你的问题,请参考以下文章