在項目中用到Express做服務器,使用了http-proxy-middleware來代理API請求。
http-proxy-middleware
http-proxy-middleware 官方文檔: https://www.npmjs.com/package/http-proxy-middleware
中文文檔:https://www.cnblogs.com/zhaoweikai/p/9969282.html
http-proxy-middleware用於將請求轉發給其他服務器。
eg:
var express = require('express');
var proxy = require('http-proxy-middleware');
var app = express();
app.use('/api', proxy({target: 'http://10.119.168.87:4000', changeOrigin: true}));
app.listen(3000);
說明:我們利用express在3000端口啟動了一個小型的服務器,利用了app.use('/api', proxy({target: 'http://10.119.168.87:4000/', changeOrigin: true}))
這句話,使發到3000端口的/api請求轉發到了4000端口。即請求http://localhost:3000/api
相當於請求http://10.119.168.87:4000/api
。
中間件:
app所掛載的"中間件"以及"路由"都在app._router.stack這個數組變量里面,每個"中間件",或者"路由"都是一個對象,他們以數組元素的形式存在app._router里面。
"中間件",或者"路由"的對象結構
//這是一個express.static();中間件在app._router.stack里面存儲的數據結構 //pathToRegexp=require("path-to-regexp"); { handle: [Function: serveStatic] //中間件回調函數,比如: app.use(express.static("/public")),那么這里的handle=express.static("/public") name: 'serveStatic', //中間件的函數名,或者路由的函數名,假設中間件為 fn,那么name=fn.name params: undefined, path: undefined, keys: [], regexp: /^\/theme\/?(?=\/|$)/i, //匹配的路徑,比如: app.use("/static",express.static("/public"));這里的regexp=pathToRegexp("/static"); route: undefined }
1. 銷毀中間件,找到對應的中間件對象,刪除元素, 2. 替換中間件,找到對應的中間件對象,重寫handle,regexp屬性 3. 動態添加,老辦法,使用app.use()
項目中:
將json數據全部代理出去:json格式
{ name:'itc', ip:'10.33.69.76', port:'8080' }
例如,訪問本地地址:http://127.0.0.1/itc 會代理到 http://10.33.69.76:8080/itc上
因為有用到增刪改查的功能,所以動態修改json數據,都要重新綁定代理
//proxyClear 清空中間件,防止重復添加 function proxyClear(){ let stack = app._router.stack; for(let i=stack.lenght-1;i>=0;i--){ let item = stack[i]; if(item.name ==="middleware"){ //添加的中間件的name為“middleware” stack.splice(i,1) } } }
添加代理
//proxyTable 數據代理 function proxyTable(data){ //清空之前的中間件 proxyClear(); for(index in data){ let item = data[index]; let name = '/'+item.name; let ip = 'http://'+item.ip+':'+item.port; app.use(name,proxy({ target:ip, changeOrigin:true })) } }
app.use('/api', proxy(options)),相當於本地服務器監聽到客戶端請求的‘/api’接口時,執行的回到是上邊的middleware中間件函數,從上邊可以看出,該函數中將請求轉發到代理服務器。
最后代理不成功:訪問代理地址404
原因:因為涉及的功能比較多,所以單獨寫了一個文件,在這個子文件中有單獨使用app,最后將app export出去,並在index.js文件中import進來,並將子文件使用app.use。
改:在子文件中添加監聽端口,監聽子文件的中間件,在子文件中定義的中間件通過子文件中定義的端口(3000)來訪問,在子文件中定義的接口‘get’通過父文件中監聽的端口(8080)來訪問。
index.js
var express = require("express"); var app = express(); var example = require('../router/example');//子文件 app.use('/example',example)
app.listen(8080)
example.js
var express = require("express"); var app = express();
//proxyClear 清空中間件,防止重復添加 function proxyClear(){ let stack = app._router.stack; for(let i=stack.lenght-1;i>=0;i--){ let item = stack[i]; if(item.name ==="middleware"){ //添加的中間件的name為“middleware” stack.splice(i,1) } } }
//proxyTable 數據代理 function proxyTable(data){ //清空之前的中間件 proxyClear(); for(index in data){ let item = data[index]; let name = '/'+item.name; let ip = 'http://'+item.ip+':'+item.port; app.use(name,proxy({ target:ip, changeOrigin:true })) } }
app.get('/get',function(req,res){
proxyTable(data);
//設置響應的http狀態,並向瀏覽器發送數據
res.status(200).send(data);
})
//子文件app中需要有個端口 用來訪問中間件
app.listen(3000)
//這是一個express.static();中間件在app._router.stack里面存儲的數據結構
//pathToRegexp=require("path-to-regexp");
{
handle: [Function: serveStatic]
//中間件回調函數,比如: app.use(express.static("/public")),那么這里的handle=express.static("/public")
name: 'serveStatic',
//中間件的函數名,或者路由的函數名,假設中間件為 fn,那么name=fn.name
params: undefined,
path: undefined,
keys: [],
regexp: /^\/theme\/?(?=\/|$)/i,
//匹配的路徑,比如: app.use("/static",express.static("/public"));這里的regexp=pathToRegexp("/static");
route: undefined
}
知道了中間件數據的存儲結構后,我們就可以很方便的銷毀中間或者替換中間件,或者自己實現app.unuse()函數了
具體操作
1. 銷毀中間件,找到對應的中間件對象,刪除元素,
2. 替換中間件,找到對應的中間件對象,重寫handle,regexp屬性
3. 動態添加,老辦法,使用app.use()