配置http-proxy-middleware能够很容易地在connect, express, browser-sync实现http代理node
http-proxy-middleware 是基于node-http-proxy实现的中间件git
- /api 请求代理到http://www.example.org的例子
var express = require('express'); var proxy = require('http-proxy-middleware'); var app = express(); app.use('/api', proxy({target: 'http://www.example.org', changeOrigin: true})); app.listen(3000);
var express = require('express') var httpProxy = require('http-proxy') var options = {target: "http://jsonplaceholder.typicode.com/users",changeOrigin: true}; var httpProxyServer = httpProxy.createProxyServer(options); function jsonHttpProxy(req, res) { httpProxyServer.web(req, res); } var app = express() app.use('/users', jsonHttpProxy) app.listen(3002)
由上述代码能够看出,当要访问/users时,须要target中对应代理网站中也设置对应的/users路径github
而在http-proxy-middleware中有一个req.url的设置,能够根据当前访问路径自动映射代理网站相应路径web
httpProxyServer.web()表示代理http或者https常规的代理链接,而想要代理websocket的链接则须要使用httpProxyServer.ws()方法ajax
logger.js和errors.js分别用于输出日志和错误信息这里不做分析express
在indexjs中能看到主入口文件,下面这段省略的源码能充分反映普通请求代理中http-proxy-middleware和node-http-proxy的关系json
var httpProxy = require('http-proxy') function HttpProxyMiddleware (context, opts) { …… return middleware var proxy = httpProxy.createProxyServer({}) function middleware (req, res, next) { …… var activeProxyOptions = prepareProxyRequest(req) proxy.web(req, res, activeProxyOptions) …… } }
与三中的代码比较最主要的区别是对options作了处理,也就是activeProxyOptions = prepareProxyRequest(req),下面分析prepareProxyRequest函数作的处理api
以访问options = {target: "http://jsonplaceholder.typicode.com",changeOrigin: true}为例,访问http://localhost:3000/userswebsocket
function prepareProxyRequest (req) { //这一步的处理很是关键,能够将请求路径对应上代理的路径 //若是不设置这一步,那么代理的路径就是对应了target不会变化 req.url = (req.originalUrl || req.url) // proxyOptions就是原始的options var originalPath = req.url var newProxyOptions = _.assign({}, proxyOptions) //这里是处理更多变得路径代理状况,下面详细介绍 __applyRouter(req, newProxyOptions) __applyPathRewrite(req, pathRewriter) ……省略logger部分代码 return newProxyOptions }
从http-proxy-middleware文档中能够看到关于router和pathRewriter的举例用法,处理过程就是对应上面的__applyRouter和__applyRewriter方法app
__applyRouter的处理在router.js中,主要处理过程是遍历options.router,而后和请求的host或者host+path比对是否相符,而后将相对应的值赋予target;若是router是函数则传入req值,执行函数获得返回值
__applyRewriter的处理在path-rewriter.js中,主要处理过程是遍历options.pathRewrite,用正则包装key,对应value,返回一个检测并改变req.url的函数,以此对应相应的代理网站的路径
pathRewrite: { '^/api/old-path' : '/api/new-path', // rewrite path '^/api/remove/path' : '/path' // remove base path }, router: { // when request.headers.host == 'dev.localhost:3000', // override target 'http://www.example.org' to 'http://localhost:8000' 'dev.localhost:3000' : 'http://localhost:8000' }
config-factory.js用于处理传入的context和options参数
例如:处理proxy(['/api', '/ajax', '/someotherpath'], {...})的context
context-matcher.js用于检测当proxy中传入了context参数时与请求路径的比对
例如: proxy('/api', {...}) - 只能代理请求以/api开头的请求
ws代理的核心处理代码
// 这里的debounced起到了节流函数的做用,防止短期内屡次调用处理函数 var wsUpgradeDebounced = _.debounce(handleUpgrade) if (proxyOptions.ws === true) { catchUpgradeRequest(req.connection.server) } //监听upgrade function catchUpgradeRequest (server) { if (!wsInitialized) { server.on('upgrade', wsUpgradeDebounced) wsInitialized = true } } //真正调用node-http-proxy的ws方法的处理函数 function handleUpgrade (req, socket, head) { wsInitialized = true if (shouldProxy(config.context, req)) { var activeProxyOptions = prepareProxyRequest(req) proxy.ws(req, socket, head, activeProxyOptions) } }
研究http-proxy-middleware源码的初衷是想要知道node是如何作到代理请求的,进行到必定步骤才发现http-proxy-middleware并无作任何这方面的处理,只是封装了代理的步骤,让参数更灵活,因此下一步仍是要探究node-http-proxy是如何对请求作处理的
可是经过研究http-proxy-middleware不只对用法更加熟悉,还大概了解了如何作一个express插件
最后 http-proxy-middleware源码 https://github.com/chimurai/h...