Node.js 实现存储服务的上传功能【包含前后端代码】

举报
liuzhen007 发表于 2021/08/10 23:14:01 2021/08/10
【摘要】 问题解决结尾 问题上传和下载功能是存储服务非常基础的功能,也是存储服务日常使用过程中最常用的功能,比如阿里云的OSS、腾讯云的COS、百度云的BOS等。当然,我们也可以自己研发私有化的对象存储服务,那么就会涉及到除了自己处理客户端逻辑外,还需要自己处理服务器的上传和下载逻辑。今天的问题就是讨论如何实现自定义的上传功能,涉及前端代码和后端代码。 解决 上传功能前端实现本地上传的方式大体有两种,...

问题

解决

结尾

问题

上传和下载功能是存储服务非常基础的功能,也是存储服务日常使用过程中最常用的功能,比如阿里云的OSS、腾讯云的COS、百度云的BOS等。当然,我们也可以自己研发私有化的对象存储服务,那么就会涉及到除了自己处理客户端逻辑外,还需要自己处理服务器的上传和下载逻辑。

今天的问题就是讨论如何实现自定义的上传功能,涉及前端代码和后端代码。

解决

上传功能

前端实现本地上传的方式大体有两种,一种是原生的 ajax 方式,另一种是借助第三方工具,比如 axios 等。

前端代码

方法一、

接下来,先介绍 ajax 的使用方式,首先创建一个 FormDate 对象,将待上传文件关联到 file 参数中,最后把 FormDate 对象赋值到 data 参数中进行上传发送。以下是实例代码(建议根据自己的实际情况进行修改):

var formdata = new FormData();
formdata.append("file", file);
$.ajax({
    type: 'post',
    dataType: 'json',
    url: uploadurl
    data: formdata,
    contentType: false,
    processData: false
}).success((data) => {

}).error((data, timeout, err) => {

})

方法二、

现在,我们介绍一下如何利用第三方工具 axios 实现上传功能,同样,先创建一个 FormData 对象,给对应的 file 表单项赋值,然后调用 axios 的 post 方法就行了。以下是实例代码(建议根据自己的实际情况进行修改):

let formData=new FormData();
formData.append('file',file);
let config = {
    headers: {
        'Content-Type': 'multipart/form-data;charset=UTF-8'
    }
};

axios.post(uploadurl,formData,config).then(({data})=>{
});

后端代码

Node.js 处理服务端的上传逻辑时,一般可以考虑 multer 中间件,它是用于处理文件上传的利器,主要跟 express 框架搭配使用,但是,仅支持表单 MIME 编码为 multipart/form-data 类型的数据请求。

实例代码:

var multer = require('multer');
var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    var type = file.mimetype.split("/")[0];
    switch(type){
      case "image":
        cb(null, './images');
        break;
      case "audio":
      case "video":
        cb(null, './movies');
        break;
      default:
        cb(null, './uploads');
    }
  },
  filename: function (req, file, cb) {
    cb(null, file.originalname);
  }
});
var upload = multer({
  storage: storage
});

// api
app.post("/api/upload", upload.single('file'), Admincontroller.postupload);

// postupload
exports.postupload = function (req, res) {
  // 解决跨域问题 
  res.header("Access-Control-Allow-Origin", "*")
  res.header("Access-Control-Allow-Methods", "*")
  res.header("Access-Control-Allow-Headers", "*")
  res.header("Access-Control-Allow-Credentials", "true")
  res.header("Cache-Control", "no-cache")
  res.header("content-type", "application/json;charset=UTF_8")

  if ("OPTIONS" == req.method) {
    console.log("===> options reqest");
    res.body = 200;
    return;
  }

  var file = req.file;
  console.log("===> upload file: " + JSON.stringify(file))
  var body = req.body;
  console.log("===> upload body: " + JSON.stringify(body))
  ......
  // 处理音视频类型的文件
    case 0: // 视频
    case 1: // 音频
    default: //视频 音频
      {
        var des = "./movies/";
        var trans = body.dtranscode;
        var taskId = body.id;
        file.path = des + filename;
        file.originalname = filename;
        var filearr = filename.split(".");
        filearr.pop();
        var path = filearr.join('.');
        var tmppath = des + path;
        var exitst = fs.existsSync(tmppath);
        if (!exitst) {
          fs.mkdirSync(tmppath);
        }
        var newfilename = filename + body.dzchunkindex;
        fs.renameSync(file.path, tmppath + "/" + newfilename);
        if (body.dzchunkindex * 1 + 1 == body.dztotalchunkcount * 1) {
          var files = fs.readdirSync(tmppath);
          for (var i = 0; i < files.length; i++) {
            fs.appendFileSync(file.path + "", fs.readFileSync(tmppath + "/" + filename + i));
            fs.unlinkSync(tmppath + "/" + filename + i);
          }
          fs.rmdirSync(tmppath);
        }
        return res.json({
          code: 0,
          success: 1
        });
      }

结尾

基于 Node.js 实现存储服务的上传功能就介绍差不多了,明天,我们讲一讲下载的问题。大家好,我是 liuzhen007,中国邦德,中国一个会敲代码的邦德,欢迎大家关注我。

日历打卡(8月更文挑战)

image.png

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。