问题
上传和下载功能是存储服务非常基础的功能,也是存储服务日常使用过程中最常用的功能,比如阿里云的OSS、腾讯云的COS、百度云的BOS等。当然,我们也可以自己研发私有化的对象存储服务,那么就会涉及到除了自己处理客户端逻辑外,还需要自己处理服务器的上传和下载逻辑。今天的问题就是讨论如何实现自定义的上传功能,涉及前端代码和后端代码。
解决
上传功能
前端实现本地上传的方式大体有两种,一种是原生的 ajax 方式,另一种是借助第三方工具,比如 axios 等。
前端代码
方法一、
接下来,先介绍 ajax 的使用方式,首先创建一个 FormDate 对象,将待上传文件关联到 file 参数中,最后把 FormDate 对象赋值到 data 参数中进行上传发送。以下是实例代码(建议根据自己的实际情况进行修改):
varformdata=newFormData(); formdata.append("file", file); $.ajax({ type: 'post', dataType: 'json', url: uploadurldata: formdata, contentType: false, processData: false}).success((data) => { }).error((data, timeout, err) => { })
方法二、
现在,我们介绍一下如何利用第三方工具 axios 实现上传功能,同样,先创建一个 FormData 对象,给对应的 file 表单项赋值,然后调用 axios 的 post 方法就行了。以下是实例代码(建议根据自己的实际情况进行修改):
letformData=newFormData(); formData.append('file',file); letconfig= { headers: { 'Content-Type': 'multipart/form-data;charset=UTF-8' } }; axios.post(uploadurl,formData,config).then(({data})=>{ });
后端代码
Node.js 处理服务端的上传逻辑时,一般可以考虑 multer 中间件,它是用于处理文件上传的利器,主要跟 express 框架搭配使用,但是,仅支持表单 MIME 编码为 multipart/form-data 类型的数据请求。
实例代码:
varmulter=require('multer'); varstorage=multer.diskStorage({ destination: function (req, file, cb) { vartype=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); } }); varupload=multer({ storage: storage}); // apiapp.post("/api/upload", upload.single('file'), Admincontroller.postupload); // postuploadexports.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; } varfile=req.file; console.log("===> upload file: "+JSON.stringify(file)) varbody=req.body; console.log("===> upload body: "+JSON.stringify(body)) // 处理音视频类型的文件case0: // 视频case1: // 音频default: //视频 音频 { vardes="./movies/"; vartrans=body.dtranscode; vartaskId=body.id; file.path=des+filename; file.originalname=filename; varfilearr=filename.split("."); filearr.pop(); varpath=filearr.join('.'); vartmppath=des+path; varexitst=fs.existsSync(tmppath); if (!exitst) { fs.mkdirSync(tmppath); } varnewfilename=filename+body.dzchunkindex; fs.renameSync(file.path, tmppath+"/"+newfilename); if (body.dzchunkindex*1+1==body.dztotalchunkcount*1) { varfiles=fs.readdirSync(tmppath); for (vari=0; i<files.length; i++) { fs.appendFileSync(file.path+"", fs.readFileSync(tmppath+"/"+filename+i)); fs.unlinkSync(tmppath+"/"+filename+i); } fs.rmdirSync(tmppath); } returnres.json({ code: 0, success: 1 }); }
结尾
基于 Node.js 实现存储服务的上传功能就介绍差不多了,明天,我们讲一讲下载的问题。大家好,我是 liuzhen007,中国邦德,中国一个会敲代码的邦德,欢迎大家关注我。
作者简介:😄大家好,我是 Data-Mining(liuzhen007),是一位典型的音视频技术爱好者,前后就职于传统广电巨头和音视频互联网公司,具有丰富的音视频直播和点播相关经验,对 WebRTC、FFmpeg 和 Electron 有非常深入的了解,😄公众号:玩转音视频。同时也是 CSDN 博客专家、华为云享专家(共创编辑)、InfoQ 签约作者,欢迎关注我分享更多干货!😄