背景:前端
前端用a標籤發起下載文檔的get請求java
node中間層接到get請求後將請求轉發到java後端node
java後端返回文檔流傳遞給node中間層數據庫
好處:json
後端的java業務邏輯層接口、數據庫不向外部暴露,node中間層進行安全驗證及請求轉發後端
1.前端發起請求api
<a download={`${filename}文件.doc`} href={`${domain}/api/word/download?a=${fileid}&b=${filename}> 下載文件 </a>
2.koa 中間層轉發promise
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對象轉換爲流,直接返回給前端便可app