Node 代理訪問的實(shí)現(xiàn)
NODE代理訪問
1. 場景
- 本地開發(fā),代理訪問,防止跨域(一般通過webpack配置代理即可),特殊情況如攜帶一些自定義的登錄cookie則需要通過自己寫node
- 作為一種server中間層,單線程異步可以緩解服務(wù)器壓力。長鏈接websocket通常使用node搭建
2. 技術(shù)框架
- node - koa2 體量小,輕便易用。
- 路由koa-router koa配套路由,中間件支持async
- koa2-request 基于async對 request的封裝,這里本人git上找的,可靠性帶考量,若基于生產(chǎn)環(huán)境建議使用request自行封裝
- koa-bodyparser 請求參數(shù)解析格式化-中間件
3. 上代碼
3.1 創(chuàng)建應(yīng)用 app.js
const Koa = require('koa')
const bodyParser = require('koa-bodyparser')
// 路由
const router = require('./router')
const app = new Koa()
app.use(
bodyParser({
// 返回的對象是一個(gè)鍵值對,當(dāng)extended為false的時(shí)候,鍵值對中的值就為'String'或'Array'形式,為true的時(shí)候,則可為任何數(shù)據(jù)類型。
extended: true
})
)
3.2 允許跨域 app.js
app.use(async (ctx, next) => {
ctx.set('Access-Control-Allow-Origin', '*')
ctx.set('Access-Control-Allow-Headers', 'content-type')
ctx.set(
'Access-Control-Allow-Methods',
'OPTIONS,GET,HEAD,PUT,POST,DELETE,PATCH'
)
await next()
})
3.2 使用路由
// app.js
app.use(router.routes())
// router.js
const Router = require('koa-router')
let koaRequest = require('./httpRequest')
const router = new Router()
router.get('/*', async (ctx, next) => {
const url = setQuestUrl(ctx.url)
try {
let res = await koaRequest(url, 'GET', ctx)
ctx.body = res
} catch (err) {
ctx.body = err
}
})
router.post('/*', async (ctx, next) => {
const url = setQuestUrl(ctx.url)
try {
let res = await koaRequest(url, 'POST', ctx)
ctx.body = res
} catch (err) {
ctx.body = err
}
})
function setQuestUrl(url) {
if (/^\/t/.test(url)) {
return 'host1'+ url.replace(/^\/t/, '')
}
if (/^\/xt/.test(url)) {
return 'host2' + url.replace(/^\/xt/, '')
}
}
module.exports = router
- router.get('/*', async (ctx, next) => {}) koa路由 ‘/*' 為通配符,匹配所有g(shù)et請求;next方法調(diào)用表示進(jìn)入下一個(gè)中間件;
- ctx請求上下文,ctx.request.body post請求參數(shù)
- koa的中間件原理 洋蔥圈模型:

const Koa = require('koa2');
const app = new Koa();
// logger
app.use(async (ctx, next) => {
console.log('第一層洋蔥 - 開始')
await next();
const rt = ctx.response.get('X-Response-Time');
console.log(`${ctx.method} ${ctx.url} - ${rt}`);
console.log('第一層洋蔥 - 結(jié)束')
});
// x-response-time
app.use(async (ctx, next) => {
console.log('第二層洋蔥 - 開始')
const start = Date.now();
await next();
const ms = Date.now() - start;
ctx.set('X-Response-Time', `${ms}ms`);
console.log('第二層洋蔥 - 結(jié)束')
});
// response
app.use(async ctx => {
console.log('第三層洋蔥 - 開始')
ctx.body = 'Hello World';
console.log('第三層洋蔥 - 結(jié)束')
});
app.listen(8000);
// 輸出
第一層洋蔥 - 開始
第二層洋蔥 - 開始
第三層洋蔥 - 開始
第三層洋蔥 - 結(jié)束
第二層洋蔥 - 結(jié)束
第一層洋蔥 - 結(jié)束
setQuestUrl 此方法主要是將前端訪問的路徑,根據(jù)第一級轉(zhuǎn)發(fā)到不同的host上
例如: /t -> host1
3.3 轉(zhuǎn)發(fā)請求 httpRequest.js
本例主要為了代理訪問并攜帶Cookie, const.js 為寫死的要攜帶的cookie
let koa2Req = require('koa2-request')
let constConfig = require('./const')
let iToken = constConfig.iToken
let koaRequest = async function(url, method, ctx) {
let options = {
method: method,
uri: url,
timeout: 120000,
body: ctx
? {
...ctx.request.body
}
: null,
headers: {},
json: true // Automatically stringifies the body to JSON
}
options.headers['Cookie'] = `i-token=${iToken}` //設(shè)置cookie
let res = await koa2Req(options)
return res.body
}
// node-mon
async function getTestToken() {
if (!constConfig.iToken) {
let url = `http://xt.eqxiu.com/tui/app/radar/test/getToken?companyId=${constConfig.companyId}&staffId=${constConfig.staffId}`
try {
let res = await koaRequest(url, 'GET')
iToken = res.obj
console.log('token已拿到:' + iToken)
} catch (e) {
console.log(e)
}
}
}
getTestToken()
module.exports = koaRequest
3.4 最后設(shè)置端口等
const app = require('./app')
//const createWebsocket = require('./websocket')
const server = require('http').createServer(app.callback())
server.setTimeout(2 * 60 * 1000) //設(shè)置超時(shí)時(shí)間
const { PORT = 3000 } = process.env
server.listen(PORT, () => {
console.log(`Listening on port ${PORT}`)
})
3.5 本地開發(fā),熱重啟
安裝 nodemon
yarn add nodemon
設(shè)置忽略監(jiān)聽
nodemon.josn node項(xiàng)目根目錄下
{
"ignore": ["node_modules/*"] //忽略node_modules下文件修改的監(jiān)聽
}
package.josn
通過npm run server啟動
{
"dependencies": {
"koa": "^2.8.1",
"koa-bodyparser": "^4.2.1",
"koa-router": "^7.4.0",
"koa2-request": "^1.0.4",
"nodemon": "^1.19.1"
},
"scripts": {
"server": "nodemon index.js"
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Pycharm配置Node.js運(yùn)行js代碼詳細(xì)過程
在PyCharm中寫JavaScript代碼并進(jìn)行調(diào)試是非常方便的,但是有些用戶可能對如何在PyCharm中準(zhǔn)確地運(yùn)行JavaScript代碼感到困惑,這篇文章主要給大家介紹了關(guān)于Pycharm配置Node.js運(yùn)行js代碼的相關(guān)資料,需要的朋友可以參考下2023-11-11
node.js中的http.response.writeHead方法使用說明
這篇文章主要介紹了node.js中的http.response.writeHead方法使用說明,本文介紹了http.response.writeHead的方法說明、語法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下2014-12-12
Node.js 實(shí)現(xiàn)簡單的接口服務(wù)器的實(shí)例代碼
這篇文章主要介紹了Node.js 實(shí)現(xiàn)簡單的接口服務(wù)器的實(shí)例代碼,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-05-05
React+react-dropzone+node.js實(shí)現(xiàn)圖片上傳的示例代碼
本篇文章主要介紹了React+react-dropzone+node.js實(shí)現(xiàn)圖片上傳的示例代碼,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-08-08
HTTP JSON接口模擬工具Interfake快速入門教程
這篇文章主要為大家介紹了HTTP JSON接口模擬工具Interfake快速入門教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
利用Node.js和MySQL實(shí)現(xiàn)創(chuàng)建API服務(wù)器
這篇文章主要為大家詳細(xì)介紹了如何使用Node.js和MySQL創(chuàng)建API服務(wù)器的步驟,這也是從前端邁向全棧的一個(gè)開始,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2024-01-01
基于Koa(nodejs框架)對json文件進(jìn)行增刪改查的示例代碼
這篇文章主要介紹了基于Koa(nodejs框架)對json文件進(jìn)行增刪改查的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02
node.js+express制作網(wǎng)頁計(jì)算器
這篇文章主要介紹了node.js+express制作網(wǎng)頁計(jì)算器的相關(guān)資料,需要的朋友可以參考下2016-01-01

