【问题标题】:Upload Images, Videos to Node.js WebService and store in Azure Blob Storage将图像、视频上传到 Node.js WebService 并存储在 Azure Blob 存储中
【发布时间】:2015-11-30 09:30:22
【问题描述】:

我创建了一个 Node.js Webservice,它在帖子正文中使用 Json 对象,并且在同一个对象中我需要传递图像/视频(不确定是否可能)媒体文件,并且需要上传相同的媒体文件到 Azure Blob 存储。

Azure 存储提供了我们上传流的库。但是在上传到 Azure blob 存储之前,如何将文件从应用程序上传到 node.js 服务器。

这个概念必须适用于 Windows、Android 和 IOS 平台。

【问题讨论】:

    标签: node.js azure blob


    【解决方案1】:

    如果您的服务器托管在 Web 应用程序上并假设它是由 expressjs 构建的,@Alex Lau 提供了一个很好的观点。

    此外,这里还有另外 2 个用于快速处理上传文件的库。我想给你一些代码 sn-ps 来处理上传文件并使用这些库放入 expressjs 中的 blob 存储:

    1,connect-busboy

    var busboy = require('connect-busboy');
    var azure = require('azure-storage');
    var fs = require('fs'); 
    var path = require('path');
    var blobsrv = azure.createBlobService(
        accountname,
        accountkey
    )
    
    router.post('/file', function (req, res, next) {
       var fstream;
        var uploadfolder = path.join(__dirname, '../files/');
       if (mkdirsSync(uploadfolder)) {
            req.pipe(req.busboy);
            req.busboy.on('file', function (fieldname, file, filename) {
               console.log("Uploading: " + filename);
                fstream = fs.createWriteStream(uploadfolder + filename);
                file.pipe(fstream);
                fstream.on('close', function () {
                    //res.redirect('back');
                    blobsrv.createBlockBlobFromLocalFile('mycontainer',filename,uploadfolder + filename, function (error, result, response) {
                        if (!error) {
                            res.send(200, 'upload succeeded');
                        } else {
                            res.send(500, 'error');
                        }
                    })
                });
            });
        }
    })
    
    function mkdirsSync(dirpath, mode) {
        if (!fs.existsSync(dirpath)) {
            var pathtmp;
            dirpath.split("\\").forEach(function (dirname) {
                console.log(dirname);
                if (pathtmp) {
                    pathtmp = path.join(pathtmp, dirname);
                }
                else {
                    pathtmp = dirname;
                }
                if (!fs.existsSync(pathtmp)) {
                    if (!fs.mkdirSync(pathtmp, mode)) {
                        return false;
                    }
                }
            });
        }
        return true;
    }
    

    2,formidable

    var formidable = require('formidable')
    router.post('/fileform', function (req, res, next) {
        var form = new formidable.IncomingForm();
        form.onPart = function (part){
            part.on('data', function (data){
                console.log(data);
                var bufferStream = new stream.PassThrough();
                bufferStream.end(data);
                blobsrv.createBlockBlobFromStream('mycontainer', part.filename, bufferStream, data.length, function (error, result, response){
                    if (!error) {
                        res.send(200,'upload succeeded')
                    } else {
                        res.send(500,JSON.stringify(error))
                    }
                })
            })
       }
        form.parse(req);
        //res.send('OK');
    })
    

    如果您使用带有 Node.js 作为后端的移动应用来处理这些工作流,我们可以创建自定义 API,并以 base64 代码传输媒体内容。

    在移动应用中:

    var azure = require('azure');
    var fs = require('fs');   
    var path = require('path');
    exports.register = function (api) {
            api.post('upload',upload);
    }
    function upload(req,res){
            var blobSvc = azure.createBlobService(
                req.service.config.appSettings.STORAGE_ACCOUNTNAME,
                req.service.config.appSettings.STORAGE_ACCOUNTKEY
            );
            var decodedImage = new Buffer(req.body.imgdata, 'base64');
            var tmpfilename = (new Date()).getTime()+'.jpg';
            var tmpupload = 'upload/';
            mkdirsSync(tmpupload);
            var filePath = tmpupload+tmpfilename;
            fs.writeFileSync(filePath,decodedImage); blobSvc.createBlockBlobFromFile(req.body.container,tmpfilename,filePath,req.body.option,function(error,result,response){
                if(!error){
                    res.send(200,{result:true});
                }else{
                    res.send(500,{result:error});
                }
            })
    }
    

    在移动应用程序中,我使用了标志性框架集成的 ng-cordova 插件来处理相机事件。 这是控制器和服务器脚本 sn-p。供您参考:

    控制器js:

    $scope.getpic = function(){
        var options = {
          quality: 10,
          destinationType: Camera.DestinationType.DATA_URL,
          sourceType: Camera.PictureSourceType.CAMERA,
          allowEdit: false,
          encodingType: Camera.EncodingType.JPEG,
          targetWidth: 100,
          targetHeight: 100,
          popoverOptions: CameraPopoverOptions,
          saveToPhotoAlbum: false
        };
        $cordovaCamera.getPicture(options).then(function(imageData) {
          console.log(imageData);
          return blobService.uploadBlob(objectId,imageData);
        }, function(err) {
          // error
        }).then(function(res){
          console.log(JSON.stringify(res));
        });
      }; 
    

    服务器js(blobService):

    factory('blobService',function($q){
           return{
                  uploadBlob:function(container,imgdata,option){
                         var q = $q.defer();
                         mobileServiceClient.invokeApi('blobstorage/upload',{
                               method:"post",
                               body:{
                                      container:container,
                                      imgdata:imgdata,
                                      option:{contentType:'image/jpeg'}
                               }
                         }).done(function(res){
                               console.log(JSON.stringify(res.result));
                               if(res.result.blob !== undefined){
                                      q.resolve(res.result.blob);
                               }
                               if(res.result.url !== undefined){
                                      q.resolve(res.result.url);
                               }
                         });                  
                         return q.promise;
                  }
           }
    })
    

    【讨论】:

      【解决方案2】:

      也许您可以考虑使用 multipart/form-data 代替 JSON,因为有一个很好的库(expressjs/multer,假设您使用 express)来处理 node.js 中的文件上传。

      只要你从multer得到文件,剩下的就很简单了,如下:

      app.post('/profile', upload.single('avatar'), function (req, res, next) {
          blobService.createBlockBlobFromLocalFile('avatars', req.file.originalname, req.file.path, function(error, result, response) {
          });
      });
      

      对于 iOS 和 Android,还有很多库允许 multipart/form-data 请求,例如 iOS 中的 AFNetworking 和 Android 中的 OkHttp

      【讨论】:

      • 我尝试上传图像和视频,但它可以发送媒体文件和数据,可以是字符串格式,也可以是直接在同一个请求中的 json
      • 你可以,但你必须用 base64 对它们进行编码,这需要额外的开发工作、网络带宽和计算时间。
      • 我尝试使用下面显示的概念在适用于数据和多个图像的提琴手中进行了尝试。那么使用它可以吗.... ---------------acebdf13572468 Content-Disposition: form-data;名称=“图像”;文件名="2015 年 8 月 31 日.png" 内容类型:图像/png --------------------- ------acebdf13572468 内容处置:表单数据; name="jsondata" Content-Type: application/json { "name" : "some name", "age" : 24, "dob" : "15/April/1989" } ---------- --acebdf13572468--
      猜你喜欢
      • 2020-04-09
      • 2018-12-17
      • 1970-01-01
      • 2014-05-22
      • 2018-12-28
      • 2020-11-07
      • 2020-08-12
      • 2020-01-25
      • 2021-01-16
      相关资源
      最近更新 更多