配置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...