题图 From 极客时间 From Clmjavascript
前端开发者在工做中经常遇到跨域的问题,通常咱们遇到跨域问题主要使用如下办法来解决:html
一、jsonp前端
二、corsvue
三、配置代理服务器。java
jsonp不是很灵活,只能发送get请求,不能发送psot请求,而cors虽然能够支持多种请求格式,可是若是请求携带cookie的话,还须要服务端和客户端分别配置一下,我的感受也很麻烦。node
相对于前两种,使用代理服务器解决跨域问题就简单了好多。react
浏览器因为同源策略的缘由,不一样域名之间发送ajax请求,响应的数据不会被浏览器加载。而服务器向服务器发送请求则没有同源策略的限制。jquery
下图即是代理服务器的原理了:nginx
代理服务器只是起一个中转做用,配置代理服务器的方法有不少种,好比利用apache、nginx、tomcat等等,今天给你们介绍的是用nodejs配置代理服务器,用nodejs配置代理服务器,咱们须要借助两个npm包,一个是web开发框架express,一个是express中间件http-proxy-middleware 。git
首先第一步咱们先用express搭建两个服务器,一个静态资源服务器端口号为3000,一个接口服务器端口号为5000,静态资源服务器代码以下:
var express = require('express');
var app = express();
app.use(express.static('./public'));
app.listen(3000);
而且在public文件夹下新建a.html,而且在页面中使用jquery,使用jquery发送ajax向接口服务器发送测试请求。
a.html代码以下:
接着搭建接口服务器,接口服务器端口号为5000,代码以下:
观察代码,咱们设计了三个接口,都是get请求,只是url不一样。
此时启动静态资源服务器和接口服务器,而后访问静态资源服务器下面的a.html,结果如图:
如图所示,发生跨域了,此时在静态资源服务器中安装http-proxy-middleware 中间件,并将其集成到静态资源服务器中。
代码以下:
此时重启静态资源服务器,并将啊,a.html页面中发送ajax的地址稍微改动一下,如图:
观察代码:咱们代码原来是直接请求5000端口服务器的数据,如今将其改为相对路径,相对于当前网页所在的服务器,当前的网页所在的静态服务器端口为3000。
当咱们访问:http://localhost:3000/a.html,结果如图:
看ajax请求的地址是如何拼接的:
得出结论:相对路径会被自动拼接。
再看请求的结果,成功了:
成功跨域了,固然这样说不严谨,浏览器并无参与跨域,而是页面中的ajax请求的地址仍是3000端口的服务,只不过是3000端口的服务接收到请求,将其转发给了5000端口的服务,并将5000端口的服务结果原封不动的返还给了浏览器。
回顾上面的代码,咱们只是在静态资源服务器中应用了http-proxy-middleware中间件,这个中间件的使用很是简单,分为以下几步:
一、安装并引入到项目中。
二、经过app.use挂载中间件,这里须要注意的是,在挂载这个中间件的时候,app.use须要设置一个前置路由,和项目原本的路由做区分。
调用这个中间件的时候须要设置几个经常使用参数:
一、target,指的是目标网站,或者被代理的网站。
二、changeOrigin是否更改host。默认为false,不重写。
三、pathRewrite路径重写,这个特性看需求。
简单配置一下:
若是这样配置,当a.html中发送请求时,这样写:
这个请求会被静态资源服务器转化为:
http://localhost:5000/api/a
也就是说若是不设置pathRewrite的话,页面中的请求地址会被原封不动的追加到目标服务器地址的后面。
而若是真正的接口地址是这样的:
http://localhost:5000/b
代理服务器该如何配置呢?
此时在页面中发送求请:
此时根据代理服务的重写规则,最终请求的地址为:
http://localhost:5000/b
以上即是pathRewrite的做用。
接着看changeOrigin的做用,当咱们将changeOrigin设置为true时,咱们在接口服务器打印req.headers,看看结果如何:
仔细观察host是localhost:5000,而将changeOrigin改成false呢?再次打印req.headers:
此时查看host是localhost:3000,
changeOrigin就是是否重写请求头中的host,代理服务器会在请求头中加入相应Host首部,而后目标服务器就能够根据这个首部来区别要访问的站点了。假如你在本地80端口起了apache服务器,服务器配了两个虚拟站点a.com b.com,设置代理以后而且changeOrigin为true 。此时就能够正确方法访问到虚拟主机下的文档内容。不然访问a b站点等同于访问localhost。固然若是你的服务器没有配置虚拟主机,彻底能够省略这个参数,就像上面演示的代码,彻底能够省略这个参数。由于接口服务器并无设置虚拟主机。
以上即是用nodejs搭建代理服务器的知识了,这个http-proxy-middleware中间件用的很普遍,在vue-cli或者create-react-app生成的项目中都内置了这个中间件,配置规则基本和上面相同,你们有问题能够留言。
天天进步一点点,你们共勉,虽然放假了,可是不能松懈呀。
代码地址 https://github.com/clm1100/corsAndProxy/tree/master/proxy
https://segmentfault.com/q/1010000005271156
https://segmentfault.com/q/1010000012607105