如何使用Ember Droplet将文件上传到Node.js?

时间:2014-06-25 16:33:31

标签: jquery node.js azure ember.js

我在我的应用上使用此界面上传文件:

https://github.com/Wildhoney/EmberDroplet

我的应用程序在Node.js上运行,而Ember是我正在使用的客户端框架。我还需要使用Azure存储服务来存储文件/图像上传。

然而,由于我对这个概念和工具方面非常陌生(Node和Ember,因此是EmberDroplet),我不明白如何通过Ember Droplet上传文件,然后将其发送到我的节点服务器要将其上传到Azure。

我已经安装了Azure-Storage软件包,并在Node.js上直接测试了它的上传。这很有效。

我已将Ember-Droplet mixin与我的界面集成,它确实将文件拖入其中或通过文件输入选择。

我不知道如何连接这两个:EmberDroplet有一个名为uploadallfiles的函数,它似乎将提供的文件数组作为输入并从中创建一个XHR对象,并在它返回其jQuery promise之前,它发送XHR请求。

我的问题是:如何设置我的应用程序,以便在执行uploadallfiles时,我的node.js服务器可以访问它们,以便它可以将它们上传到azure,然后在模型中存储对它的引用文件与?

相关联

后续问题是这样的:Azure关于将Azure与节点一起使用的教程展示了如何通过它的文件路径获取本地存储的文件,然后将其上传到Blob存储。然而,

  1. 客户端应用程序是否可以向服务器发送本地文件路径并仍然可以正常工作?我的印象是服务器端代码无法访问客户端本地存储。
  2. Azure可以使用XHR而不是文件路径上传吗?
  3. 是否需要通过azure-storage上传文件的特定格式?

1 个答案:

答案 0 :(得分:7)

回答你的问题:

  1. 不,服务器无法直接访问客户端存储 - 您必须将文件本身发布到服务器(而不仅仅是路径)
  2. 您可以从客户端javascript直接上传到Azure,但它相对复杂。您希望为客户端代码生成共享访问签名(SAS)以用作上载端点,然后使用jQuery将PUT添加到该URL。 Gaurav Mantri在他的博客上有一个很好的例子:http://gauravmantri.com/2013/02/16/uploading-large-files-in-windows-azure-blob-storage-using-shared-access-signature-html-and-javascript/
  3. Blob存储对于大多数意图和目的非常类似于您的本地文件系统,因此没有您需要担心的主要限制。如果您的用户正在上传文件,您应该可以将它们直接推送到blob存储。
  4. 关于你关于Ember和Ember-Droplet的问题,Ember-Droplet有一些很棒的示例代码,显示了你需要实现服务器端的内容。请查看以下摘录:https://github.com/Wildhoney/EmberDroplet/blob/master/example/node-server/server.js

    // Responsible for handling the file upload.
    app.post('/upload', function(request, response) {
    
        var files       = request.files.file,
            promises    = [];
    
        /**
         * @method uploadFile
         * @param file {Object}
         * @return {Object}
         */
        var uploadFile = function uploadFile(file) {
    
            var deferred = new Deferred();
    
            fileSystem.readFile(file.path, function (error, data) {
                var filePath = __dirname + '/uploaded-files/' + file.name;
                fileSystem.writeFile(filePath, data, function() {});
                deferred.resolve(file.name);
            });
    
            return deferred.promise;
    
        };
    
        if (!Array.isArray(files)) {
    
            // We're dealing with only one file.
            var promise = uploadFile(files);
            promises.push(promise);
    
        } else {
    
            // We're dealing with many files.
            files.forEach(function(file) {
                var promise = uploadFile(file);
                promises.push(promise);
            });
    
        }
    
        promisedIo.all(promises).then(function(files) {
            response.send({ files: files, success: true });
            response.end();
        });
    
    });
    

    显然,假设您使用的是Express,但无论如何它都表明您需要实现与dropletUrl相对应的post方法(如控制器中指定的那样:{{ 3}})处理接收文件。

    然后,您希望将uploadFile的实现替换为使用Azure节点SDK写入Azure存储的内容。我把你可以使用的这个小功能放在一起:

    var azure = require('azure-storage');
    var blobService = azure.createBlobService('mystorageaccountname', 'mystorageaccountkey', 'https://mystorageaccountname.blob.core.windows.net');
    
    var uploadFile = function(file) {
        var deferred = new Deferred();
    
        blobService.createBlockBlobFromFile('mycontainername', file.name, file.path, function(error, result, response) {
            if (!error) {
                deferred.resolve(file.name);
            }
        });
    
        return deferred.promise;
    };
    

    如果将该功能放入Ember-Droplet示例服务器实现中而不是现有服务器实现中,您最终会将服务器写入blob存储。请注意,您需要使用有效的存储帐户名,存储帐户密钥和blob容器名来代替上面的占位符(包括在azure.createBlobService调用中指定的主机字符串中)。