koa中间层 文件下载的请求转发
背景:
前端用a标签发起下载文档的get请求
node中间层接到get请求后将请求转发到java后端
java后端返回文档流传递给node中间层
好处:
后端的java业务逻辑层接口、数据库不向外部暴露,node中间层进行安全验证及请求转发
1.前端发起请求
<a download={`${filename}文件.doc`} href={`${domain}/api/word/download?a=${fileid}&b=${filename}> 下载文件 </a>
2.koa 中间层转发
router.get('/word/download',async (ctx,next)=>{ let {a,b,date} = ctx.query; date = date || timeStamp2String(false,'short'); let file = await request({ uri:'word', qs:{ orgNo:a } }); let s = new Readable; s.push(file); s.push(null); let docx = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'; let doc = 'application/msword'; ctx.set('content-type',docx); ctx.set('content-disposition',`attachment;filename*=UTF-8''${encodeURIComponent(b)}.docx`); ctx.body = s; });
3.request方法请求java后端
import request from 'request-promise'; function reqGetStreamData(params){ let {uri,qs} = params; return new Promise((resolve,reject)=>{ request({ uri:`${domain}api/jgs/${uri}`, qs, encoding:null, headers: { 'User-Agent': 'Request-Promise', 'Content-type':docx }, json: false }).then(data => { resolve(data); }, err => { let errData = { status:1, data:err, statusInfo:'失败' } reject(errData); }).catch(err => { let obj = { status: 1, data: err, statusInfo: '未知错误!' }; reject(obj); }); }); }
原理就是:将java后端返回的文件流被request转换为buffer对象,然后用stream.Readable将buffer对象转换为流,直接返回给前端即可