Koa代理Http请求的示例代码

Koa 代理http请求,解决跨域问题

1、为什么用Koa做跨域代理?

"最初为了解决跨域问题,我把站点部署到了nginx上就解决了问题。一次偶然的面试机会,面试官提出了一个假设我需要对提交api和api返回的数据进行适配,那么nginx是不是就无法满足了。当然这个问题的提出,让我考虑到其实如果自己搭一个站点,通过这个站点进行转发,适配第三方api的请求和应答不就好了。那么要搭一个站点的语言其实有很多,例如.net,java,nodejs,php...,那为什么最后选择nodejs呢?对于我来说最重要的原因,应该就是nodejs的轻量级和javascript语言亲和性。

2、搭建nodejs应用

由于Koa2刚出,毕竟学技术,那么就学最新的。

既然搭建程序那么就从程序的入口开始做,首先写程序的路由

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;

其次就是处理代理的请求

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();

}

})

}

由此简单的几行代码就实现了通过nodejs实现跨域的请求代理。 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;

}

}

以上是 Koa代理Http请求的示例代码 的全部内容, 来源链接: utcz.com/z/313004.html

回到顶部