Koa 代理http請(qǐng)求,解決跨域問(wèn)題

10年積累的網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先做網(wǎng)站后付款的網(wǎng)站建設(shè)流程,更有上虞免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
1、為什么用Koa做跨域代理?
"最初為了解決跨域問(wèn)題,我把站點(diǎn)部署到了nginx上就解決了問(wèn)題。一次偶然的面試機(jī)會(huì),面試官提出了一個(gè)假設(shè)我需要對(duì)提交api和api返回的數(shù)據(jù)進(jìn)行適配,那么nginx是不是就無(wú)法滿足了。當(dāng)然這個(gè)問(wèn)題的提出,讓我考慮到其實(shí)如果自己搭一個(gè)站點(diǎn),通過(guò)這個(gè)站點(diǎn)進(jìn)行轉(zhuǎn)發(fā),適配第三方api的請(qǐng)求和應(yīng)答不就好了。那么要搭一個(gè)站點(diǎn)的語(yǔ)言其實(shí)有很多,例如.net,java,nodejs,php...,那為什么最后選擇nodejs呢?對(duì)于我來(lái)說(shuō)最重要的原因,應(yīng)該就是nodejs的輕量級(jí)和javascript語(yǔ)言親和性。
2、搭建nodejs應(yīng)用
由于Koa2剛出,畢竟學(xué)技術(shù),那么就學(xué)最新的。
既然搭建程序那么就從程序的入口開(kāi)始做,首先寫(xiě)程序的路由
const fs = require('fs')
const Router = require('koa-router');
const {httpHandle} = require('../Infrastructure/httpHandle');
const koaBody = require('koa-body')({
multipart :true
});
const render = (page) => {
return new Promise((resolve, reject) => {
let viewUrl = `./view/${page}`
fs.readFile(viewUrl, "binary", (err, data) => {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
}
let api = new Router();
api.get('*', httpHandle)
.post('*', koaBody, httpHandle)
.put('*', koaBody, httpHandle).del('*', koaBody, httpHandle);
let common = new Router();
common.get('*', async (ctx) => {
ctx.body = await render('index.html');
})
let router = new Router();
router.use('/api', api.routes(), api.allowedMethods());
router.use('/', common.routes(), common.allowedMethods());
module.exports = router;其次就是處理代理的請(qǐng)求
const httpRequest = (ctx) => {
return new Promise((resolve) => {
delete ctx.request.header.host;
const options = {
host,
port,
path: ctx.request.url.substr(4, ctx.request.url.length),
method: ctx.request.method,
headers: ctx.request.header
}
let requestBody='',
body,
head,
chunks = [],
fileFields,
files,
boundaryKey,
boundary,
endData,
filesLength,
totallength = 0;
if (ctx.request.body) {
console.log(ctx.request.header['content-type'])
if (ctx.request.header['content-type'].indexOf('application/x-www-form-urlencoded') > -1) {
requestBody = query.stringify(ctx.request.body);
options.headers['Content-Length'] = Buffer.byteLength(requestBody)
} else if (ctx.request.header['content-type'].indexOf('application/json') > -1) {
requestBody = JSON.stringify(ctx.request.body);
options.headers['Content-Length'] = Buffer.byteLength(requestBody)
} else if (ctx.request.header['content-type'].indexOf('multipart/form-data') > -1) {
fileFields = ctx.request.body.fields;
files = ctx.request.body.files;
boundaryKey = Math.random().toString(16);
boundary = `\r\n----${boundaryKey}\r\n`;
endData = `\r\n----${boundaryKey}--`;
filesLength = 0;
Object.keys(fileFields).forEach((key) => {
requestBody += `${boundary}Content-Disposition:form-data;name="${key}"\r\n\r\n${fileFields[key]}`;
})
Object.keys(files).forEach((key) => {
requestBody += `${boundary}Content-Type: application/octet-stream\r\nContent-Disposition: form-data; name="${key}";filename="${files[key].name}"\r\nContent-Transfer-Encoding: binary\r\n\r\n`;
filesLength += Buffer.byteLength(requestBody,'utf-8') + files[key].size;
})
options.headers['Content-Type'] = `multipart/form-data; boundary=--${boundaryKey}`;
options.headers[`Content-Length`] = filesLength + Buffer.byteLength(endData);
} else {
requestBody = JSON.stringify(ctx.request.body)
options.headers['Content-Length'] = Buffer.byteLength(requestBody)
}
}
const req = http.request(options, (res) => {
res.on('data', (chunk) => {
chunks.push(chunk);
totallength += chunk.length;
})
res.on('end', () => {
body = Buffer.concat(chunks, totallength);
head = res.headers;
resolve({head, body});
})
})
ctx.request.body && req.write(requestBody);
if (fileFields) {
let filesArr = Object.keys(files);
let uploadConnt = 0;
filesArr.forEach((key) => {
let fileStream = fs.createReadStream(files[key].path);
fileStream.on('end', () => {
fs.unlink(files[key].path);
uploadConnt++;
if (uploadConnt == filesArr.length) {
req.end(endData)
}
})
fileStream.pipe(req, {end: false})
})
} else {
req.end();
}
})
}由此簡(jiǎn)單的幾行代碼就實(shí)現(xiàn)了通過(guò)nodejs實(shí)現(xiàn)跨域的請(qǐng)求代理。 github鏈接
nginx代理config配置 如下
server {
listen 1024;
server_name tigrex:1024;
root home/TuoTuo.v2.UI;
index index.html;
access_log logs/tigrex.access.log;
error_log logs/tigrex.error.log;
charset utf-8;
location /api {
proxy_pass http://127.0.0.1:1023/;
proxy_set_header Host $host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
try_files $uri $uri/ /index.html;
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
分享標(biāo)題:Koa代理Http請(qǐng)求的示例代碼
當(dāng)前地址:http://www.chinadenli.net/article36/gidesg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航、面包屑導(dǎo)航、ChatGPT、品牌網(wǎng)站設(shè)計(jì)、搜索引擎優(yōu)化、自適應(yīng)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)