1. 程式人生 > >node中間層實現文件上傳

node中間層實現文件上傳

ron 發送 port 不存在 不支持 middle host pan code

  一般情況下,前端的文件上傳一般都是通過form表單的(<input type="file" />)來完成文件的上傳,如果使用node中間層完成跨域,文件的上傳就需要在node中間層處理成可讀流,轉成formData完成轉發。

一、form表單文件上傳

  這是最常見的文件上傳方式,通過form表單實現,簡單實用,設置一下method、enctype、action屬性就可以了,多文件上傳需要設置multiple屬性(部分瀏覽器支持還是有些問題的)。

1 <form method="post" enctype="multipart/form-data" action="/api/upload">
2
<input type="text" name="username"> 3 <input type="password" name="password"> 4 <input type="file" name="file"> 5 <input type="submit"> 6 </form>

二、FormData實現文件上傳

  FormData對象用以將數據編譯成鍵值對,以便向後臺發送數據。其主要用於發送表單數據,但亦可用於發送帶鍵數據(keyed data),而獨立於表單使用。對部分瀏覽器對multiple屬性不支持的情況,可以使用formData的提交方式完成。

1 <!-- 獲取上傳文件轉成formData類型的文件 -->
2 <input multiple id="file" name="file" type="file" />
3 <button id="btn">提交</button>
 1 const oFile = document.getElementById(‘file‘)
 2 const oBtn = document.getElementById(‘btn‘)
 3 
 4 oBtn.addEventListener(‘click‘, () => {
 5     files = oFile.files
6 const formData = new FormData() 7 formData.append(‘file‘, files[0]) 8 formData.append(‘file1‘, files[1]) 9 10 fetch(‘/api/upload‘, { 11 method: "POST", 12 body: formData 13 }) 14 })
  • 使用fetch請求不要設置Content-Type,否則無法請求
  • fetch請求默認是不帶cookie

三、node中間層完成文件上傳跨域

  跨域是因為瀏覽器的同源策略造成,跨域的方法有很多中,這裏使用的是node中間層代理完成(服務端之間的請求是不存在跨域問題)。

  node無法直接解析上傳的文件,需要引入拓展包connect-multiparty完成,這樣就可以拿到文件數據。

  拿到上傳文件,需要在node中轉發請求後臺server,這裏的文件不能直接發給後臺,需要將上傳的文件使用fs.createReadStream轉成可讀流,同時引入 form-data 包(node環境是沒有formData對象的),這樣就可以實現node中間層轉發文件類型

  node部分代碼:

 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 
10 router.post(‘/upload‘, multipartMiddleware, function (req, res) {
11     // console.log(req.body, req.files);
12 
13     const { path: filePath, originalFilename } = req.files.file
14     const newPath = path.join(path.dirname(filePath), originalFilename)
15 
16     fs.rename(filePath, newPath, function (err) {
17         if (err) {
18             return;
19         }
20         else {
21             const file = fs.createReadStream(newPath)
22             const form = new FormData()
23             form.append(‘file‘, file)
24 
25             fetch(‘http://localhost:8080/upload‘, {
26                 method: "POST",
27                 body: form
28             })
29         }
30     })
31     res.json({})
32 });
33 
34 module.exports = router; 

 

註意:

  • node無法直接解析上傳文件,需要引入npm包connect-multiparty中間件,或者引入npm包multiparty
  • node拿到文件,需要使用fs.createReadStream轉成可讀流
  • node環境沒有formData對象,需要引入npm包form-data
  • fetch請求提交formData數據,不能設置Comtemt-Type

  

  完整的代碼請參考 node中間層實現文件上傳

  如果喜歡請關註我的Github,給個Star吧,我會定期分享一些JS中的知識,^_^

node中間層實現文件上傳