我创建了一个Node.js Web服务,它将Json对象放在post主体和同一个对象中,我需要传递图像/视频(不确定是否可能)媒体文件和相同的媒体文件需要上传到Azure Blob存储。
Azure存储提供了我们上传流的库。但是,在上传到Azure blob存储之前,如何从Apps将文件上传到node.js服务器。
这个概念必须适用于Windows,Android和IOS平台。
答案 0 :(得分:2)
如果您的服务器托管在Web应用程序上并假设它是由expressjs构建的,那么@Alex Lau提供了一个很好的观点。
此外,还有另外2个用于快速处理上传文件的库。我想给你一些代码片段来处理上传文件,并使用这些库在expressjs中放入blob存储:
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;
}
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。