博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
express,koa2等node处理前端上传图片并保存到文件中
阅读量:6240 次
发布时间:2019-06-22

本文共 5249 字,大约阅读时间需要 17 分钟。

在实际的项目中,图片的处理往往是最麻烦的,无论是前后台,我自己也试手了一两个图片上传的小项目,把步骤写下来,以后自己忘记可以返回来看一下,同时希望能够帮到小伙伴们...

前端网页

框架: vue + iview等组件来实现图片的file功能 + koa2

运用iview的Upload组件

upload组件方法方式就不过多一一赘述了,在这里提几点关键点

data() { return { uploadData: { url: '', // 图片二进制的data的url articleId: '' // 这个详情的ID 后台与他绑在一起 } }}// 利用浏览器的FileReader的特性压缩并上传图片handleBeforeUpload() { let reader = new FileReader(); reader.readAsDataURL(file); reader.onloadend = (e)=> { file.url = reader.result; this.uploadData.articleId = this.$route.query.id; this.uploadData.url = file.url; }}复制代码

前端总结: 运用iview组件来构造file上传图片本身不难,官方了解api多次尝试就可以了

koa后台node框架

node后台处理图片,查了网上资料,采用了formidable的包来处理图片的,express采用formidable的npm包,而koa2采用了koa-formidable的npm包,两者没多大区别,koa-formidable只不过是formidable的再度封装和运载koa2的框架上而已

我们先看浏览器查看http的请求

图片的http请求为什么跟别的不一样,就是不一样,我们不一样,哈哈!别钻牛角,适应就行了

  • 1.引入koa-formidable
  • 2.
  • let form = formidable.parse(request);
  • 图片重命名fs,放入public文件中
  • 图片路径放回给前端

步骤并不复杂,只是本人对于node的模块不太熟悉,比如fs path模块,希望以后多多做node小项目,熟悉起来...

代码如下:

// app.jsconst Router = require('koa-router');const router = new Router();const serve = require("koa-static");const formidable = require('koa-formidable'); // 图片处理const fs = require('fs'); // 图片路径const path = require('path'); // 图片路径app.use(serve(__dirname))  // 设置静态文件// 新建文件,可以去百度fs模块let mkdirs = (dirname, callback)=> {    fs.exists(dirname, function(exists) {        if (exists) {            callback();        } else {            mkdirs(path.dirname(dirname), function() {                fs.mkdir(dirname, callback);            });        }    });};router.post('/upload/image', function (ctx, next) {    let form = formidable.parse(request);    function formImage() {    	return new Promise((resolve, reject) => {    		form((opt, {fields, files})=> {        	let url = fields.url;        	let articleId = fields.articleId;        	let filename = files.file.name;        	console.log(files.file.path);        	let uploadDir = 'public/upload/';    	        let avatarName = Date.now() + '_' + filename;    	        mkdirs('public/upload', function() {                	fs.renameSync(files.file.path, uploadDir + avatarName); //重命名                	resolve(config[env].host + '/' + uploadDir + avatarName)                	// http://localhost:6001/public/upload/1513523744257_WX20171205-150757.png                })            })    	})    }    let url = await formImage();    return {flag: '1',msg:'',data: url} // 路径返回给前端});app  .use(router.routes())  .use(router.allowedMethods());复制代码

要点

1.设置静态文件 app.use(serve(__dirname))

根据个人喜好设置静态路径默认的设置方法: app.use(serve(__dirname) + '/public') resolve(config[env].host + '/upload/' + avatarName)也可以这样设置,app.use(serve(__dirname) + '/public/upload') resolve(config[env].host + '/' + avatarName)复制代码

2.fs.exists新建文件,用于存放图片

新建一个匿名函数来回调判断有无该文件,有则存入,无则新建文件

let mkdirs = (dirname, callback)=> {    fs.exists(dirname, function(exists) {        if (exists) {            callback();        } else {            mkdirs(path.dirname(dirname), function() {                fs.mkdir(dirname, callback);            });        }    });};复制代码

3.koa框架存在异步,所以必须用await来终结异步操作

至于async/await可以去百度一下

function formImage(){    return new Promise((resolve)=> {        // 处理图片        resolve(url)    })}let url = await formImage();复制代码

4.formidable处理图片,获取图片

let form = formidable.parse(request);form((opt, obj)=> {    // 代码如上})// 因为obj是个对象并有fields, files两个参数,那我直接这样处理:form((opt, {fields, files})=> {    // 代码如上    // 上面的代码最重要的就是下面这一句     // fs.renameSync(opt1,opt2) opt1 form处理的图片路径而不是fileds.url二进制的路径, opt2则是重命名的图片名称    fs.renameSync(files.file.path, uploadDir + avatarName);})做完就可以 ctx.body = {data: url, msg: '', flag: '1'} 返回给前端复制代码

在另个项目中,同样的代码却报错了... 我也是一脸懵逼

以上是在mac笔记本操作,没有发现错误,但在window系统下却发现图片上传不成功,一个致命的错误

fs.js:439  return binding.rename(pathModule._makeLong(oldPath),                 ^Error: EXDEV, cross-device link not permitted 'C:\Users\CLi\AppData\Local\Temp\df99513a93a1cbfbc26e076f8ae08b92'    at Object.fs.renameSync (fs.js:439:18)复制代码

查询了报错的原因:是跨分区重命名文件,会有权限问题

网友解决方法之一:

用了以上文章的解决方法: 也报错了 util.pump is not undefined,这下懵逼了

用了node的pipe流方法

let readStream = fs.createReadStream(files.file.path)let writeStream = fs.createWriteStream(uploadDir + avatarName);readStream.pipe(writeStream);复制代码

代码如下:

exports.editImages = async(ctx, next)=> {	let form = formidable.parse(ctx.request);    form.encoding = 'utf-8';    form.keepExtensions = true; //保留后缀    mkdirs('public/upload');    let imgPlay = new Promise((resolve, reject) => {	form((opt, {fields, files})=> {	let articleId = fields.articleId;	let filename = files.file.name;        let avatarName = Date.now() + '_' + filename;        let readStream = fs.createReadStream(files.file.path)		let writeStream = fs.createWriteStream(uploadDir + avatarName);		readStream.pipe(writeStream);                // fs.rename(files.file.path, uploadDir + avatarName); //window报错了重命名        	resolve({        		url: config[env].host + '/' + uploadDir + avatarName        	})        	// http://localhost:6001/public/upload/1513523744257_WX20171205-150757.png    })    });    let imageData = await imgPlay;	ctx.body = {flag: '1' ,msg:'',data: imageData}}复制代码

完美解决跨平台的图书上传问题

项目中还有不如,如:前端上传图片的压缩问题,涉及多张上传问题,都没有实践,以后继续更新不足

这是我试水node的小项目的案例,请多指教

项目github地址:

转载地址:http://dadia.baihongyu.com/

你可能感兴趣的文章
Java+SpringBoot实现四则运算
查看>>
【转载】Discriminative Learning和Generative Learning
查看>>
Git中的AutoCRLF与SafeCRLF换行符问题
查看>>
通过Process启动外部程序
查看>>
那些在django开发中遇到的坑
查看>>
cocos2dx lua 绑定之二:手动绑定自定义类中的函数
查看>>
IE CSS HACK
查看>>
北风设计模式课程---深入理解[代理模式]原理与技术
查看>>
php课程 4-14 数组如何定义使用
查看>>
winform托盘时,要运行一个实例,解决办法
查看>>
vagrant up 失败解决办法
查看>>
mysql AM/PM to 24 hours fromat
查看>>
远程唤醒UP Board
查看>>
网页打印
查看>>
Loading——spin.js
查看>>
Hadoop完全分布式环境搭建(四)——基于Ubuntu16.04安装和配置Hadoop大数据环境...
查看>>
Mule ESB工程的部署
查看>>
分离被碰撞物体, 求碰撞冲量
查看>>
js移动端 可移动滑块
查看>>
【kruscal】【最小生成树】poj3522 Slim Span
查看>>