简体   繁体   English

使用Meteor,jQuery和AWS开发工具包将浏览器直接上传到S3

[英]Direct Browser Upload to S3 with Meteor, jQuery and the AWS SDK

I have got into almost every resource on the topic, but still need your help to make this work. 我已经接触到有关该主题的几乎所有资源,但仍然需要您的帮助才能完成此工作。 I want to directly upload files to my S3 directly from the browser in my Meteor app. 我想直接从Meteor应用程序中的浏览器直接将文件上传到S3。 For this, I provide a signed url to the client just like in this simplified example: 为此,就像下面的简化示例一样,我向客户端提供了一个签名的URL:

Meteor.methods({
    requestUpload: function(filename) {
        var fut = new Future();
        new Fiber(function() {
            var params = {
                Bucket: MY_BUCKET,
                Key: new Date().getTime() + "_" + filename
            };
            var surl = s3.getSignedUrl('putObject', params, function(err, surl) {
                if (!err) {
                    console.log("signed url: " + surl);
                    fut.return(data);
                } else {
                    console.log("Error signing url " + err);
                    fut.return();
                }
            });
        }).run();
        return fut.wait();
    }
}

The client then calls this method, obtains the signed url which looks like this 然后,客户端调用此方法,获得如下所示的签名网址

https://mybucket.s3-eu-west-1.amazonaws.com/1382890365957_myfile.png?AWSAccessKeyId=AKBLABLA&Expires=1382891265&Signature=BLABLA

and tries to upload the file with a POST request using jQuery like in this snippet: 并尝试使用jQuery来上传带有POST请求的文件,如以下代码段所示:

Template.form.events({
    'submit form': function(e, t) {
        e.preventDefault();
        var fileInput = t.find("input[type=file]");
        for (var i = 0; i < fileInput.files.length; i++) {
            var file = fileInput.files[i];
            Meteor.call("requestUpload", file.name, function(err, surl) {
                if (!err) {
                    console.log("signed url: " + surl);
                    var reader = new FileReader();
                    reader.onload = function(event) {

                    // Here I am trying to upload, it fails
                        $.post(surl, reader.result, function(data, status) {
                            console.log("status: " + status);
                            console.log("data: " + data);
                        });
                    };
                    reader.readAsDataURL(file);
                } else {
                    console.log(err);
                }
            });
        }
    }
});

I want to use jQuery because I thing it's probably a good way to cover a lot of browsers and browser versions. 我想使用jQuery,因为我认为这可能是覆盖许多浏览器和浏览器版本的好方法。 I also checked my CORS configuration for this particular bucket, it looks like this: 我还检查了该特定存储区的CORS配置,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

The credentials, that I configure my SDK with on the server are ensured to be alright, they have admin permissions and I am using them all the time for putting and getting objects in the S3 from the server. 确保在服务器上配置我的SDK的凭据没有问题,它们具有管理员权限,并且我一直在使用它们来从服务器放置和获取S3中的对象。 Also, if I sign a url for a GET call on a private file, the signed url is valid. 另外,如果我在私有文件上签名GET调用的URL,则签名的URL有效。 I am probably doing something wrong with the post call. 我可能在邮局中做错了事。

Any help is very appreciated! 任何帮助都非常感谢!

To get this working I had to add a couple of parameters to the s3.getSignedUrl call: 为了使此工作正常进行,我必须在s3.getSignedUrl调用中添加几个参数:

ContentType: mimeType,
Body: '',
"ACL": 'public-read'

Full method: 完整方法:

Meteor.methods({
    requestUpload: function(filename, mimeType) {
        var fut = new Future();
        new Fiber(function() {
            var params = {
                Bucket: MY_BUCKET,
                Key: new Date().getTime() + "_" + filename,
                ContentType: mimeType,
                Body: '',
                "ACL": 'public-read'
            };
            var surl = s3.getSignedUrl('putObject', params, function(err, surl) {
                if (!err) {
                    console.log("signed url: " + surl);
                    fut.return(surl);
                } else {
                    console.log("Error signing url " + err);
                    fut.return();
                }
            });
        }).run();
        return fut.wait();
    }
}

Same problem here - I think this is because of Meteor not allowing CORS in the application header. 同样的问题-我认为这是因为Meteor不允许在应用程序标头中使用CORS。 I'm also trying to solve this very urgently. 我也正试图非常紧急地解决这个问题。

The problem can be that you requesting a SignedUrl for a PUT request but you later on POST the file to S3. 问题可能是您为PUT请求请求了SignedUrl,但稍后将文件POST到S3。 You should PUT the file to S3 not POST. 您应该将文件放入S3而不是POST。

SignedUrls only allow GET and PUT right now. SignedUrl现在仅允许GET和PUT。

For more info see this answer: upload-file-from-angularjs-directly-to-amazon-s3-using-signed-url 有关更多信息,请参见以下答案: 将文件从angularjs直接上传到amazon-s3-using-signed-url

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM