我需要从供应商的Web服务中检索文件,并将它们推送到唯一的blob容器中,以便用户拥有唯一的“工作区”。本质上,我将从供应商处获取文件,并且用户可以通过自己的Blob容器中的文件进行编辑,以免彼此交叉工作文件。我有唯一的blob容器,但需要从供应商的API中“下载”
/获取文件,并将其推送到blob容器中。我能够成功检索文件,这将是分别获取PDF,文本文件和图像的调用……但是,如果尝试将它们上传到Azure
Blob存储,则在Node.js中会出现以下错误:
TypeError:无法读取null的属性“ length”
我认为我需要在客户端将文件编码为base64才能正确获取长度,并且已经看到了一些使用具有toDataURL的Canvas的示例,但是不确定这是否是从本质上直接下载并推送至的最佳方法。
Azure Blob存储,尤其是因为我有PDF之类的文件(不确定PDF是否可以使用base64编码)。
这是调用服务的我的AngularJS控制器(请注意,实际端点可能会根据调用的文件而有所不同,因此我正在使用文件的客户端GET来控制用户可以以表格形式输入的变量):
$scope.getFiles = function () {
$.ajax({
url: 'http://vendorwebservice.net/ws/file1',
type: "GET",
success: function (result) {
console.log(result);
var filename = 'Texture_0.png';
$http.post('/postFile', { filename: filename, file: result }).success(function (data) {
console.log(data);
}, function (err) {
console.log(err);
});
alert("Files Retrieved!");
},
error: function (error) {
console.log("Failed to download image!");
}
})
}
这是我的后端/节点/快速代码:
app.post('/postFile', function (req, res, next) {
var filename = req.body.filename;
var file = req.body.file;
var base64Data;
fileBuffer = decodeBase64Image(file);
blobSvc.createBlockBlobFromText('blob5', filename, fileBuffer.data, { 'contentType': fileBuffer.type }, function (error, result, response) {
if (!error) {
console.log("Uploaded" + result);
}
else {
console.log(error);
}
});
})
// Decode file for upload
function decodeBase64Image(dataString) {
var matches = dataString.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/),
response = {};
if (matches.length !== 3) {
return new Error('Invalid input string');
}
response.type = matches[1];
response.data = new Buffer(matches[2], 'base64');
return response;
}
更新1:
根据加里(Gary)的建议,我尝试了以下操作,但由于我的供应商API没有文件URI,而是在GET上生成文件的端点(又使我迷失了如何传递端点),因此使代码有些混乱与加里(Gary)的例子很有意义)。例如,我的供应商端点“
http://vendorapi.net/ws/texture_0
”返回一个名为“ Texture_0.png”的文件。
前端角度代码:
$scope.getFromVendor = function () {
var filename = 'Texture_0.png';//jpg,txt...
$http.post('/uploadapifiles', { filename: filename, url: 'http://vendorapi.net/ws/texture_0' }).success(function (data) {
console.log(data);
}, function (err) {
console.log(err);
});
}
服务器端下载处理(我认为这是最混乱的过程:
app.get(http://vendorapi.net/ws/texture_0', function (req, res, next) {
res.download('http://vendorapi.net/ws/texture_0' + req.params.filename);
})
服务器端上传处理:
app.post('/uploadapifiles', function (req, res, next) {
var filename = req.body.filename;
var r = request(req.body.url).pipe(fs.createWriteStream('http://vendorapi.net/ws/texture_0' + filename))
r.on('close', function () {
blobsrv.createBlockBlobFromLocalFile('blob5', filename, 'http://vendorapi.net/ws/texture_0' + filename, function (error, result, response) {
if (!error) {
console.log("Uploaded" + result);
}
else {
console.log(error);
}
});
})
});
按照您的原始想法,首先您需要在客户端获取文件内容数据,然后将数据发布到Express Web服务器。
如果您获取的文件很大,则会减慢您的站点速度,因为文件数据将通过HTTP传输两次,并且可能会发生其他问题。
此外,在我的测试项目中,几乎不直接处理文件内容数据。
因此,我尝试了另一种想法作为解决方法。
我只是将获取特定文件的API发布到服务器,将文件另存为文件保存在服务器目录中,然后将文件上传到服务器端的存储。这是我的代码段:
角形前端:
$scope.upload =function(){
var filename = (new Date()).getTime()+'.pdf';//jpg,txt...
$http.post('http://localhost:1337/uploadfile', { filename: filename, url: 'http://localhost:1337/output/123.pdf'}).success(function (data) {
console.log(data);
},function(err){
console.log(err);
});
}
后端:
我怀疑您获取文件形式的API会像后面一样。
router.get('/output/:filename', function (req, res, next) {
res.download('upload/'+req.params.filename);
})
后请求处理程序利用包请求,并且无需弄清文件类型或编码类型,createBlockBlobFromLocalFile
便会将文件上传到您在Blob存储上提供的位置,API参考:
router.post('/uploadfile', function (req, res, next) {
var request = require('request');
var filename = req.body.filename;
var tmpFolder = 'upload/', //this folder is to save files download from vendor URL, and should be created in the root directory previously.
tmpFileSavedLocation = tmpFolder + filename; //this is the location of download files, e.g. 'upload/Texture_0.png'
var r = request(req.body.url).pipe(fs.createWriteStream(tmpFileSavedLocation))//this syntax will download file from the URL and save in the location asyns
r.on('close', function (){
blobsrv.createBlockBlobFromLocalFile('vsdeploy', filename, tmpFileSavedLocation, function (error, result, response) {
if (!error) {
console.log("Uploaded" + result);
}
else {
console.log(error);
}
});
})
})
问题内容: 我有这个简单的服务器/客户端应用程序。我正在尝试让服务器通过OutputStream(FileOutputStream,OutputStream,ObjectOutputStream等)发送文件并在客户端将其接收,然后再将其保存到实际文件中。问题是,我尝试这样做,但一直失败。每当我创建文件并将从服务器接收到的对象写入文件时,都会得到损坏的图像(我只是将其另存为jpg,但这无关紧要)。这
问题内容: 由于我是Web服务的新手,请您告诉我问题的答案。我的问题是 我想实现一个Web服务,当客户端调用此Web服务时,该服务会向客户端发送pdf文件。 请有人帮我提供一段不错的代码或解释。 现在可以请一个人解决我的错误。 12-23 09:42:48.429:调试/安装(32):DexInv:-开始’/data/app/vmdl33143.tmp’— 12-23 09:42:51.708:调
我有一个基于Spring(Spring Security,Spring控制器和MVC)的项目,所以在我的超文本标记语言页面中,我必须允许文件下载。 我处理事件并使用基于jquery插件的代码 在我的控制器中: 但它在Spring Security性方面有问题,比如这个post x-frame,在internet explorer上不起作用。那么,有没有一种不用插件就能下载存储在我服务器上的文件的方
我目前有问题下载到函数tmp dir下面是我的代码。函数返回
问题内容: 我在服务器端有一个Struts2操作,用于文件下载。 但是,当我使用jQuery调用操作时: 在Firebug中,我看到数据是通过 Binary流 检索的。我想知道如何打开 文件下载窗口 ,用户可以用它在本地保存文件吗? 问题答案: 这是我现在建议的一些注意事项: 需要相对较新的浏览器 如果预期文件 很大,则 您可能应该执行与原始方法(iframe和cookie)类似的操作,因为以下某
我试图使简单的文件服务器。我有Node.js后端与MongoDB GridFS存储存储文件。我从服务器获取文件通过。在前端,我使用Angular。我有两个主要问题: 当我使用Blob提供下载服务时,变成:“d1c393df-b0d9-4ae5-befe-8d45b183eb54…”友善的我读了很多关于它的文档,没有找到任何解决方案 当我只通过Express提供下载服务而不进行身份验证时,文件会正确