記錄一次node中台轉發表單上傳文件到后台過程


首發掘金  記錄一次node中台轉發表單上傳文件到后台過程 本篇跟掘金為同一個作者leung
 
公司幾個項目都是三層架構模式即前台,中台(中間層),后台。前台微信端公眾號使用vue框架,后台管理前端使用react,中台(中間層)使用node,后台使用java。此次說的是后台關鍵上傳數據文件時遇到的一個bug,因為是三層架構,前台表單會先提交到node中間層,然后再通過node中間層轉發到java后台保存並讀取文件數據。 此次遇到了一個bug當表單提交到node中間層的時候node接口request可以獲取得到表單上傳的文件信息,就在node端創建http請求轉發到后台的時候后台報錯了: the request was rejected because no multipart boundary was found后台收到的接口請求中得不到boundary信息,此時已確定node創建的http請求中 headers中Content-Type為multipart/form-data,很顯然java后台沒收到上傳文件信息,通過在頁面創建form表單使用后台上傳接口地址發現后台可以上傳,這證明后台接口沒問題,node中台接口也能收到form表單上傳文件數據,那么范圍進一步縮小問題就出現在node http請求轉發到后台這步的問題了。既然后台接口請求體中沒有boundary那么問題就出現在創建請求的時候少給了東西后台了,Google+百度了一下找到的解決方式在發現都不行,不能說完全沒有用但是還是找到了方向。后台要的是表單數據,那node中台轉發的時候就轉發一個表單數據。於是找到了 form-data這個包及 connect-multiparty中間件。 先插入一段代碼然后再分析;

node-fetch方式發送請求到后台

 1 const fs = require('fs')
 2 const path = require('path')
 3 const FormData = require('form-data')
 4 const express = require('express')
 5 const fetch = require('node-fetch')
 6 const router = express.Router()
 7 const multipart = require('connect-multiparty');
 8 var multipartMiddleware = multipart()
 9 router.post('/uploadFile', multipartMiddleware,  (req, res) => {
10   const { path: filePath, originalFilename } = req.files.file
11   const newPath = path.join(path.dirname(filePath), originalFilename) // 得到newPath新地址用於創建讀取流
12   fs.rename(filePath, newPath, (err) => {
13     if (err) {
14       return;
15     } else {
16       const file = fs.createReadStream(newPath) //創建讀取流
17       const form = new FormData() // new formdata實例
18       form.append('file', file) // 把文件加入到formdata實例中
19       fetch('后台接口上傳地址like:https://ip:端口/接口', {
20         method: "POST",
21         body: form,
22         headers: form.getHeaders()  // 這步非常重要一定要把formdata的headers放在請求體headers中我發現網上很多例子講的都沒這個headers,沒有這個后台還是會報boundary的錯因為boundary是在request headers中
23         }).then(res => res.json()).then(data => {
24           res.send({data: data}) //將上傳結果返回給前端
25         })
26       }
27    })
28 });
這種方式沒有使用node http請求使用到了fetch,只是一種請求方式,換成axios其實也是一樣的,最主要的是發送請求的時候除了往formdata中append file文件信息外,headers一定要是formdata的headers不然后台還是接收不到request中的boundary。

node http方式發送請求到后台

 1 const fs = require('fs')
 2 const path = require('path')
 3 const FormData = require('form-data')
 4 const express = require('express')
 5 var http = require('http');
 6 const router = express.Router()
 7 const multipart = require('connect-multiparty');
 8 var multipartMiddleware = multipart()
 9 router.post('/uploadFile', multipartMiddleware,  (req, res) => {
10   const { path: filePath, originalFilename } = req.files.file
11   const newPath = path.join(path.dirname(filePath), originalFilename) // 得到newPath新地址用於創建讀取流
12   fs.rename(filePath, newPath, (err) => {
13     if (err) {
14       return;
15     } else {
16       const file = fs.createReadStream(newPath) //創建讀取流
17       const form = new FormData() // new formdata實例
18       form.append('file', file) // 把文件加入到formdata實例中
19       var request = http.request({
20           method: 'post',
21           host: 'http://ip:port',
22           path: '/xxxx', //上傳接口
23           headers: form.getHeaders()  //formdata的headers
24       });
25       form.pipe(request);
26       request.on('response', (response) => {
27         res.send({data: response})
28       });
29     }
30   })
31 })

這種方式使用的是node中http方式,相關注意事項其實跟node-fetch差不多只是發送的差別而已。

其實項目中我們是把請求方式http單獨抽取到一個文件中的這樣方便管理,這里只是為了方便說明情況把它放到node中台接口中。其實不管是哪種方式都是換湯不換葯的都是將append后formdata中的文件信息同時還有formdata headers發送到后台接口就可以了。
今天周末有時間總結一下,最后如果有不對的地方希望大家指正一起學習,謝謝!
首發掘金  記錄一次node中台轉發表單上傳文件到后台過程 本篇跟掘金為同一個作者leung

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM