当我们在使用Node搭建服务端的时候,我们可能会碰到需要接收 压缩文件
的情况,例如:接收前端提交的压缩包、解压等,我们这里演示一下如何 接收
与 解压
前端
html
<p id="desc">点击或拖拽文件到网页内即可上传</p>
|
css
* { margin: 0; padding: 0; list-style: none; border: none; box-sizing: border-box; }
html, body { width: 100vw; height: 100vh; }
#desc { position: fixed; top: 50%; left: 50%; letter-spacing: 1em; font-size: 1.25rem; color: #7c7c7c; transform: translate(-50%, -50%); z-index: -9999; }
|
js
(() => {
let body = document.body
body.addEventListener('dragenter', e => e.preventDefault(), false)
body.addEventListener('dragleave', e => e.preventDefault(), false)
body.addEventListener('dragover', e => e.preventDefault(), false) body.addEventListener('drop', e => { e.preventDefault() let fileList = e.dataTransfer.files beforeUpload(fileList) }, false)
body.addEventListener('click', () => { let fileInput = document.createElement('input') fileInput.type = 'file' fileInput.click() fileInput.onchange = function () { beforeUpload(this.files) } }, false)
function beforeUpload(fileList) { if (fileList.length === 0) { alert('未选择要上传的文件') return } if (fileList[0].type.indexOf("application/zip") === -1) { alert('只能上传zip格式的压缩包') return } let formData = new FormData() formData.append('file', fileList[0])
request(formData) }
function request(formData) { let xhr = new XMLHttpRequest() xhr.open('POST', '/api/upload') xhr.send(formData) xhr.onload = function () { let { response } = this response = JSON.parse(response) if (response.code === 200 && response.state === true) { alert(`上传成功`) } else { alert(`上传失败,${response.message}`) } } }
})()
|
后台
后台采用express搭建,执行以下命令进行依赖安装:
yarn add express body-parser multer compressing
|
或
npm i express body-parser multer compressing -S
|
我们的目录结构如下:
node_modules cache pages - index.html service - index.js utils - index.js main.js package.json
|
入口文件
const express = require('express') const bodyParser = require('body-parser') const router = require('./service/index') const path = require('path')
const app = express()
app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json())
app.use(express.static(path.resolve(__dirname, 'pages')))
app.use(router)
app.listen(8080, () => { console.log(`服务器运行于 http://127.0.0.1:8080`) })
|
自定义工具函数
const fs = require('fs') const compressing = require('compressing');
exports.writeFile = (filepath, data, encode) => { return new Promise((resolve, reject) => { fs.writeFile(filepath, data, encode, (err) => { if (err) reject(err) resolve() }) }) }
exports.readFile = (filepath, encode) => { return new Promise((resolve, reject) => { fs.readFile(filepath, encode, (err, data) => { if (err) reject(err) resolve(data) }) }) }
exports.extract = (filepath, outputPath) => { return compressing.zip.uncompress(filepath, outputPath, { zipFileNameEncoding: 'utf8' })
}
exports.delDir = (filepath) => {
if (fs.existsSync(filepath)) { const files = fs.readdirSync(filepath) files.forEach((file) => { const nextFilePath = `${filepath}/${file}` const states = fs.statSync(nextFilePath) if (states.isDirectory()) { this.delDir(nextFilePath) } else { fs.unlinkSync(nextFilePath) } }) fs.rmdirSync(filepath) } }
|
路由文件
const router = require('express').Router() const fs = require('fs') const multer = require('multer') const path = require('path') const { writeFile, extract, delDir } = require('../utils/index')
const filePath = path.resolve(__dirname, '../', 'cache')
router.post('/api/upload', multer().single('file'), async (req, res) => { let file = req.file
if (file.mimetype !== 'application/zip') { res.send({ code: 400, state: false, message: '不是zip文件', data: 0 }) }
try { delDir(filePath) fs.mkdirSync(filePath) let filename = path.join(filePath, file.originalname) await writeFile(filename, file.buffer, 'buffer') await extract(filename, filePath) fs.unlinkSync(filename)
res.send({ code: 200, state: true, message: 'ok' }) } catch (error) { console.log(error) res.send({ code: 400, state: false, message: 'zip文件解压失败', data: 0 }) }
})
module.exports = router
|
其他
我们解压使用的是 compressing
处理的,并且 一定要记得设置中文解码,否则可能会出现中文乱码
当然,例如 node-stream-zip
和 extract-zip
也无法解析中文,会出现乱码