Koa代理Http请求的示例代码
Koa代理http请求,解决跨域问题
1、为什么用Koa做跨域代理?
"最初为了解决跨域问题,我把站点部署到了nginx上就解决了问题。一次偶然的面试机会,面试官提出了一个假设我需要对提交api和api返回的数据进行适配,那么nginx是不是就无法满足了。当然这个问题的提出,让我考虑到其实如果自己搭一个站点,通过这个站点进行转发,适配第三方api的请求和应答不就好了。那么要搭一个站点的语言其实有很多,例如.net,java,nodejs,php...,那为什么最后选择nodejs呢?对于我来说最重要的原因,应该就是nodejs的轻量级和javascript语言亲和性。
2、搭建nodejs应用
由于Koa2刚出,毕竟学技术,那么就学最新的。
既然搭建程序那么就从程序的入口开始做,首先写程序的路由
constfs=require('fs')
constRouter=require('koa-router');
const{httpHandle}=require('../Infrastructure/httpHandle');
constkoaBody=require('koa-body')({
multipart:true
});
constrender=(page)=>{
returnnewPromise((resolve,reject)=>{
letviewUrl=`./view/${page}`
fs.readFile(viewUrl,"binary",(err,data)=>{
if(err){
reject(err)
}else{
resolve(data)
}
})
})
}
letapi=newRouter();
api.get('*',httpHandle)
.post('*',koaBody,httpHandle)
.put('*',koaBody,httpHandle).del('*',koaBody,httpHandle);
letcommon=newRouter();
common.get('*',async(ctx)=>{
ctx.body=awaitrender('index.html');
})
letrouter=newRouter();
router.use('/api',api.routes(),api.allowedMethods());
router.use('/',common.routes(),common.allowedMethods());
module.exports=router;
其次就是处理代理的请求
consthttpRequest=(ctx)=>{
returnnewPromise((resolve)=>{
deletectx.request.header.host;
constoptions={
host,
port,
path:ctx.request.url.substr(4,ctx.request.url.length),
method:ctx.request.method,
headers:ctx.request.header
}
letrequestBody='',
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)
}elseif(ctx.request.header['content-type'].indexOf('application/json')>-1){
requestBody=JSON.stringify(ctx.request.body);
options.headers['Content-Length']=Buffer.byteLength(requestBody)
}elseif(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)
}
}
constreq=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){
letfilesArr=Object.keys(files);
letuploadConnt=0;
filesArr.forEach((key)=>{
letfileStream=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{
listen1024;
server_nametigrex:1024;
roothome/TuoTuo.v2.UI;
indexindex.html;
access_loglogs/tigrex.access.log;
error_loglogs/tigrex.error.log;
charsetutf-8;
location/api{
proxy_passhttp://127.0.0.1:1023/;
proxy_set_headerHost$host;
proxy_redirectoff;
proxy_set_headerX-Real-IP$remote_addr;
proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;
}
location/{
try_files$uri$uri//index.html;
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。