文件上传笔记
前端部分使用element框架
<el-upload class='avatar-uploader' action='actionUrl' :http-request="httpRequest" :show-file-list='false' :on-success='handleSuccess'> </el-upload>
这里使用element的上传组件,
on-success 上传成功的回调,
show-file-list 是否显示上传列表,
action为组件必选参数,要填写上传地址,这里随便写了一个字符串,因为上传方法我要在httpRequest方法中重新写
http-request 自定义上传方法
async httpRequest (options) { this.fileReader = new FileReader() let file = options.file let filename = file.name if (file) { this.fileReader.readAsDataURL(file) // 读文件 } this.fileReader.onload = () => { // 文件读取后的操作 let base64Str = this.fileReader.result //得到base64串 uploadImg({ imgData: base64Str, name: filename }).then(res => { // 成功后方法 }) } }
这里新建了fileReader对象,使用readAsDataURL 异步读取文件,读取后在onload方法中得到base64字符串,
upload方法为一个上传方法,和项目中其他axios封装方法一样,接收一个上传的数据对象,并在一个管理所有请求的文件中写好请求的url,method,
后端方法 使用nodejs的 eggjs框架
在router中配置一个地址,对应一个controller
router.post(`${domain}/api/uploadImg`, controller.Controller.uploadImg);
在controller文件中 写一个uploadImg方法,
async uploadImg() { const { imgData, name } = ctx.request.body; if (!imgData) { ctx.response.body = { msg: '图片不能为空' } return; } if (!name) { ctx.response.body = { msg: '名称不能为空' } return; } const info = await ctx.service.Service.uploadImg(imgData, name) ctx.response.body = { code: info.code, data: info.data, msg: info.msg } }
主要还是service方法,
这里imgData为接收的文件内容,上传时给的是base64格式,name为上传时带来的文件名称,
使用fs模块的writeFile方法,将buffer对象中的内容写入文件中,文件生成的地址为配置的路径加上上传的文件名
async uploadImg(imgData, name) { const { ctx } = this; const url = ctx.app.config.poster; // config中配置的文件上传路径,注意要包含两个路径,一个url.dir为服务器路径 类似 “/文件夹/文件夹”,一个url.url为域名 用于返回给前端访问 try { var base64Data = imgData.replace(/^data:image\/\w+;base64,/, ""); var dataBuffer = new Buffer(base64Data, 'base64'); // 新建一个buffer对象,设置为base64格式 fs.writeFile(`${url.dir}${name}`, dataBuffer, function(err) { if(err){ console.log(err) }else{ console.log('success') } }); return { data: `${url.url}${name}`, msg: '添加图片成功' } } catch (error) { } }
至此,文件就会在服务器的指定目录中,并返回一个url地址,前端可以保存这个地址链接,此方法也可以用于富文本中的图片上传