express+multer上传图片打开乱码问题及解决

Xylona ·
更新时间:2024-09-20
· 1565 次阅读

目录

express+multer上传图片打开乱码

原因

解决方法

简单的node文件上传下载及中文乱码

1. 基于MEAN的技术栈

2. 在前端代码中放置文件上传按钮和处理表单数据

3. 后端接收上传文件

4. 处理上传文件的乱码

5. 下载文件

6. 处理下载文件的乱码

express+multer上传图片打开乱码 原因

由于使用multer处理上传图片时,multer存储的是重命名的文件,文件并没有后缀名导致文件无法在服务器直接打开,手动加上后缀名就能打开文件。

如:

解决方法

引入fs模块将文件重命名存储即可,以下用单文件上传为例:

const fs=require('fs') router.post('/imageUpload',upload.single('avatar'),function (req, res) { console.log(req.file) //获取文件后缀名 var appendName=req.file.originalname.split('.')[1] //fs重命名文件,第一个参数为上传文件绝对路径,第二个参数为相对路径 //第三个参数可选 fs.rename(req.file.path,`tmp/uploads/${req.file.filename}.${appendName}`,function (err) { if (err) throw err }) res.json({msg:'success'}) }) 简单的node文件上传下载及中文乱码 1. 基于MEAN的技术栈

使用restful风格的接口

2. 在前端代码中放置文件上传按钮和处理表单数据 <div class="upload-file btn btn-sm btn-primary mb-2">   <span><i class="fa fa-upload"></i> Upload</span>   <input type="file" class="btn btn-sm btn-primary mb-2" (change)="fileChange($event, topic)" placeholder="Upload file" accept=".csv,.xls"> </div>

处理上传文件,生成表单数据 

fileChange(event, topic) { this.topic = topic; const fileList: FileList = event.target.files; const file: File = fileList[0]; const formData: FormData = new FormData(); formData.append('_id', topic._id); formData.append('file', file, file.name); this.topicService.uploadMark(formData).subscribe((res) => { this.topic.marks = res; this.toast.setMessage('item import successfully.', 'success'); }, error => console.log(error)); } uploadMark(fileData: FormData): Observable<any> { return this.http.post('/api/upload', fileData); } 3. 后端接收上传文件

文件上传的router

export default function setRoutes(app) {   const router = express.Router(); // file uplaod router.route('/upload').post(uploadCtrl.uploadFile); // Apply the routes to our application with the prefix /api app.use('/api', router); }

在路由中,req的file字段是获取不到上传文件的,或许可以通过设置bodyParser来处理,但我这里使用一个比较常见的库multer。

npm install multer --save import * as path from 'path'; import * as multer from 'multer'; import TopicService from '../services/topic'; export default class UploadCtrl {   uploadFile = (req, res) => {     const topicService = new TopicService();     // 获取上传文件     const uploading = multer({       dest: path.join(__dirname, '../public/uploads'),     }).single('file'); // 这里的file是formData.append('file', file, file.name)里的名称     uploading(req, res, (err) => {       if (err) {         return console.error(err);       }       const topicId = req.body._id;       const uploadFile = req.file;       // 保存数据       const save = async () => {         const markList = await topicService.parseMark(uploadFile.path);         const db = await topicService.saveDB(topicId, markList);         return {           markList: markList,           db: db,         };       };       save().then((result) => {         res.status(200).json(result.markList);       }, error => {         console.error(error);       });     });   } } 4. 处理上传文件的乱码

上传的文件是一个中文的csv,解析时出现了乱码,使用iconv-lite进行转换

npm install iconv-lite --save import * as iconv from 'iconv-lite'; import * as Buffer from 'bufferhelper'; export default class IconvHelper {   /**    * 用于文件上传的转码    * @param fileStr    * @returns {string}    */   static iconv2utf8 = (fileStr) => {     return iconv.decode(fileStr, 'gbk');   }   /**    * 用于文件下载的转码    * @param fileStr    * @returns {NodeBuffer}    */   static iconv2gbk = (fileStr) => {     return iconv.encode(fileStr, 'gbk');   } }

bufferhelper是一个buffer的增强类,但这里使用后并不能正确赋值,所以这里暂且没有使用

对csv文件进行解析,生成数组,下一步可以保存到数据库

parseMark = (filePath) => {   return new Promise((resolve, reject) => {     // 读取文件内容     fs.readFile(filePath, (error, data) => {       if (error) {         return reject(error);       }       const text = IconvHelper.iconv2utf8(data);       const markList = [];       // 将文件按行拆成数组       text.split(/\r?\n/).forEach((line, index) => {         const arr = line.split(',');         if (index > 0 && arr[0]) {           markList.push({             userId: arr[0],             username: arr[1],             donePageCount: arr[2],             areaCount: arr[4],             name: arr[6],           });         }       });       resolve(markList);     });   }); } 5. 下载文件 res.setHeader('Content-disposition', `attachment; filename='${result.name}-member.csv'`); res.setHeader('Content-type', 'text/csv; charset=GBK'); res.end(IconvHelper.iconv2gbk(content)); 6. 处理下载文件的乱码

由于node.js只支持'ascii', 'utf8', 'base64', 'binary'的编码方式,不支持MS的utf8 + BOM格式,网上有说增加BOM头,如下示:

const msExcelBuffer = Buffer.concat([   new Buffer('\xEF\xBB\xBF', 'binary'),   new Buffer(IconvHelper.iconv2gbk(content)) ]);

但实际并没有起作用,最后只是简单的encode成gbk问题得到解决

res.end(IconvHelper.iconv2gbk(content));

以上为个人经验,希望能给大家一个参考,也希望大家多多支持软件开发网。



乱码 express 图片

需要 登录 后方可回复, 如果你还没有账号请 注册新账号