将图像,视频上传到Node.js WebService并存储在Azure Blob存储中

时间:2015-09-04 09:18:38

标签: node.js azure blob

我创建了一个Node.js Web服务,它将Json对象放在post主体和同一个对象中,我需要传递图像/视频(不确定是否可能)媒体文件和相同的媒体文件需要上传到Azure Blob存储。

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

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

2 个答案:

答案 0 :(得分:2)

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

此外,还有另外2个用于快速处理上传文件的库。我想给你一些代码片段来处理上传文件,并使用这些库在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插件来处理相机事件。 这是控制器和服务器脚本片段。供您参考:

控制器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;
              }
       }
})

答案 1 :(得分:0)

也许您可以考虑使用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

相关问题