为了账号安全,请及时绑定邮箱和手机立即绑定

上传图片: vue + axios + express

标签:
Vue.js

上传图片到服务器是一个很常见的需求, 应该实现起来很简单. 但是之前没这方面经验, 折腾了一番.

调研

数据库中应该只保存图片的链接, 图片保存在文件系统中, 可以是服务器本地, 可以是自己部署的独立图片服务器, 也可以是第三方服务器.

MongoDB中, BSON文件的上显示16MB. 所以如果图片不超过这个上限, 就可以存BSON; 否则要用GridFS.

对我来说, 最理想的当然是使用第三方图片服务器了. 但是现在并不想花这个钱(囧rz). 所以想先试试存在自己的服务器本地.

界面怎么写?

上传文件有个专门的控件, input[type="file"]. 浏览了几个网站的实现, 都是把input[type="file"]隐藏起来(因为它太丑), 然后在相同的区域摆上一个按钮之类的东西(好看一些), 用户点了按钮其实点击了input[type="file"].

示例如下:

<label class="btn btn-primary file-chooser">
    Change Picture
  <input type="file" accept=".jpg, .jpeg, .png" @change="uploadAvatar"></label>

webp

upload avatar

input[type="file"]支持属性accept, 上面的代码只接受.jpg, .jpeg, .png文件.

@change="uploadAvatar"是vue中监听input[type="file"]change事件. 用户选择的图片会成为e.target.files[0].

uploadAvatar(e) {
  service.uploadAvatar(e.target.files[0]);
}

请求怎么发?

我用的是axios处理请求. 搜了一下需要用multipart/form-datacontent-type发送, 具体如下:

// service.jsuploadAvatar(avatar) {    let data = new FormData();
    data.append('avatar', avatar);    return axios.post('/upload-avatar', data, {        headers: { 'content-type': 'multipart/form-data' }
    });
}

后端怎么接?

我用的是express + mongodb. 其实我本来打算存BSON的, 反正头像不用16MB那么大.

但是搜了一下可以用multer, 阴差阳错存到本地了.

npm install -S multer后:

// index.jsconst multer = require('multer');const avatarUpload = multer({ dest: 'public/avatar/' });

app.use(express.static('public'));

第二行创建了文件夹public/avatar作为存储图片的地点.
第三行是将整个public文件夹都作为静态资源, 让外部可以访问.

然后写路由:

router.post(    '/upload-avatar',
    authenticator,
    avatarUpload.single('avatar'),
    (req, res) => {        // Set { new: true } to return the updated one, rather than the original one.
        User.findByIdAndUpdate(req.user.id, { avatar: req.file.path }, { new: true }).then(user => {
            res.json({ message: "ok" });
        });
    }
);

authenticator是我在JWT上手: Express+Passport做的用户身份JWT验证逻辑, 此处请忽略. 示例代码里面没删除是因为req.user.id需要它.

avatarUpload.single('avatar')引入了multer的中间件, 读取请求中的key为avatar的文件, 返回到req.file中. req.file是一个object, 里面有mimetype等信息, 我们需要的是req.file.path, 即服务器本地的地址.

User.findByIdAndUpdate就是把这条信息更新到mongoDB中.

至此, 打完收工.

回头来看, 感觉真简单. 但是调研的时候接触到了很多听都没听过的东西, BSON, GridFS, multer, 充满不确定性 :P.



作者:柳正来
链接:https://www.jianshu.com/p/3b0c3979ebef
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。



点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 1
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消