因項目須要,後臺須要支持接收前端的壓縮文件並解析上傳至雲平臺,一頓踩坑以後基本跑通了整條流程,下面寫下來分享給那些像我同樣的node小白~javascript
本次實現中依賴了node解壓模塊unzip前端
yarn add unzip
複製代碼
以前在網上找了好多資料,基本上都是在服務器本地對各類文件進行操做,難道就沒有從前端向後臺傳、解析壓縮文件的先例嘛???java
因此,直接從前端把zip文件拋過來,get!node
項目UI是基於antd實現的,因此直接用Upload組件進行的上傳,這裏有個坑要踩,在默認設置下組件上傳會報錯:No 'Access-Control-Allow-Origin' header is present on the requested resource. 須要給組件設置屬性
headers= {{ 'X-Requested-With':null }}
windows
get是get到了,但經過fs.createReadStream()
來直接讀取拿到的buffer是老是回報這樣那樣的錯誤,通過一番苦苦搜尋,找到了這樣一種解釋:This means the library would like to do its own reading of the file rather than being given a stream of bytes for analysis.,大概意思就是node的方法但願接收的資源是資源的路徑而不是資源自己,既然這樣,那就把從前端獲取的數據先存起來好了:服務器
fs.writeFile(`${__dirname}/temp/temp.zip`, z, function(e) {
···//這裏的z就是從前端拿來的資源
}
複製代碼
這下就能夠拿到想要的zip了吧,而後就能夠隨心所欲了。antd
fs.writeFile(`${__dirname}/temp/temp.zip`, z, function(e) {
fs.createReadStream(`${__dirname}/temp/temp.zip`) //拿到zip
.pipe(unzip.Parse()) //將流流入unzip.Parse
.on('entry', function(entry: any) {
let fileName = entry.path.replace(/[\w]+\//g, '').trim() // 將路徑上的目錄都剔除掉,只留下文件名
if ( fileName !== ".DS_Store" && fileName !== "desktop.ini" && entry.type === "File") {
// 這裏的判斷是由於在解析完壓縮文件後發現每一個目錄下都有個叫.DS_Store的奇怪東西
// 查了才知道這是Mac系統的配置文件,這個當讓不是我想上傳的
// desktop.ini是windows系統的配置文件
entry.on('data', function(chunck: any) {
let bs = new Stream.PassThrough() //很奇葩,雲平臺的接口對數據有要求,不得已又又作了一次流的轉換
bs.end(chunck)
arr.push(
new Promise(function(resolve, reject) {
formUploader.putStream(token.uploadToken, `${prePath}${fileName}`, bs, putExtra, function(err, res, info) { //這是向雲平臺上傳文件的方法
if (err) {
reject(err)
}
if (info.statusCode === 200) {
resolve(res)
} else {
reject(res)
reject(info.statusCode)
}
})
})
)
})
}
})
.once('close', function() {
cb(arr) // 解壓完成執行回調
})
}
複製代碼
unzip.Parse()方法是對壓縮包進行遞歸解壓,因此才能這麼輕鬆的拿到解壓後的全部文件,給它一個大大的贊~ui