- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我的应用程序中,我希望能够将文件直接从浏览器上传到我的 AWS S3 存储桶。我的后端是 Rails,但我想避免到服务器的额外跳跃,并避免使用回形针、Carrierwave、Carrierwave_direct 等 gem ,以保持简单。我大致遵循这个tutorial来自heroku。
我正在使用 aws-sdk gem 和 jquery.fileupload.js 库。
问题是,当我尝试上传时,我从 AWS 收到了 400 错误请求。
我不认为这是 CORS 问题。我在我的存储桶上配置了 CORS,并且可以看到成功的 OPTIONS 请求,后跟文件上传的 POST 请求,该请求返回 400 错误请求。
以下是复制问题的简化演示。
这是 Controller 操作。它生成一个 AWS::S3::PresignedPost 对象,以便 View 可以使用它将文件直接发布到 S3。
def new
Aws.config.update({
region: 'us-east-1',
credentials: Aws::Credentials.new('[FILTERED]', '[FILTERED]'),
})
s3 = Aws::S3::Resource.new
bucket = s3.bucket('mybucket')
@presigned_post = bucket.presigned_post(key: "attachments/#{SecureRandom.uuid}/${filename}")
@thing = Thing.new
end
这是 View ,new.html.erb
,由上面的内容呈现,带有上传表单和处理上传的 javascript。
<div class='container'>
<%= form_for(@thing, html: { class: 'direct_upload' }) do |f| %>
<%= f.label 'Thing' %>
<%= f.file_field :attachment_url %>
<%= f.submit %>
<% end %>
</div>
<script type="text/javascript">
$(function() {
var $form = $('form.direct_upload'),
upload_url = '<%= escape_javascript(@presigned_post.url.to_s) %>',
upload_form_data = '<%= escape_javascript(@presigned_post.fields.to_json.html_safe) %>';
console.log('URL: ', upload_url);
console.log('Form data: ', upload_form_data);
if ($form.length) {
$form.find('input[type=file]').each(function(index, input) {
var $file_field = $(input);
$file_field.fileupload({
fileInput: $file_field,
url: upload_url,
type: 'POST',
autoUpload: false,
formData: upload_form_data,
paramName: 'file',
dataType: 'XML',
add: function(e, data) {
console.log('add callback fired.');
$form.submit(function(e) {
e.preventDefault();
console.log('form submitted.');
data.submit();
});
},
start: function(e) {
console.log('start callback fired');
},
done: function(e, data) {
console.log('done callback fired');
},
fail: function(e, data) {
console.log('fail callback fired');
console.log(e);
console.log(data);
}
});
});
}
});
</script>
这是从 S3 返回的响应:
<Error>
<Code>InvalidArgument</Code>
<Message>Bucket POST must contain a field named 'key'. If it is specified, please check the order of the fields.</Message>
<ArgumentName>key</ArgumentName>
<ArgumentValue></ArgumentValue>
<RequestId>[filtered]</RequestId>
<HostId>[filtered]</HostId>
</Error>
当页面加载时,您可以在 JavaScript 控制台中看到预期的输出:
URL: https://mybucket.s3.amazonaws.com/
Form data: {"key":"attachments/d6313635-9735-4b84-9985-f9f62a036de8/${filename}","policy":"[FILTERED]","x-amz-credential":"[FILTERED]/us-east-1/s3/aws4_request","x-amz-algorithm":"AWS4-HMAC-SHA256","x-amz-date":"20150809T134239Z","x-amz-signature":"[FILTERED]"}
如您所见,有一个关键字段。
当您将文件添加到文件输入字段时,add
回调将按预期触发并绑定(bind)表单的提交操作。提交表单后,请求将转到 S3,但随后会触发 fail
回调,因为返回了 400。
这个question可能描述了问题是什么,但我无法根据提供的信息解决它。
以下是从 Chrome 开发工具复制的请求/响应信息。
Remote Address:54.231.17.17:443
Request URL:https://mybucket.s3.amazonaws.com/
Request Method:POST
Status Code:400 Bad Request
Response Headers
Access-Control-Allow-Methods:GET, POST, PUT
Access-Control-Allow-Origin:*
Connection:close
Content-Type:application/xml
Date:Sun, 09 Aug 2015 12:29:57 GMT
Server:AmazonS3
Transfer-Encoding:chunked
Vary:Origin, Access-Control-Request-Headers, Access-Control-Request-Method
x-amz-id-2:ymrt0MUlhf3bKqVWj+O5jhaUPXNEXy9HQh9PABmqzDkkb4Ods3Hy1LA++8G/Svri3LcOktpnGeE=
x-amz-request-id:545E755033D285F2
Request Headers
Accept:application/xml, text/xml, */*; q=0.01
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:331
Content-Type:multipart/form-data; boundary=----WebKitFormBoundary9vtTme67oAg1OMyL
Host:braidio.s3.amazonaws.com
Origin:http://localhost:3000
Referer:http://localhost:3000/things/new
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36
Request Payload
------WebKitFormBoundary9vtTme67oAg1OMyL
Content-Disposition: form-data; name="file"; filename="my_text.txt"
Content-Type: text/plain
------WebKitFormBoundary9vtTme67oAg1OMyL--
如您所见,请求负载仅包含文件,而不包含 key 。该文件可能需要位于发布请求中的所有其他字段之后,这就是 S3 看不到关键字段的原因,如 answer 中所建议的。 .
一些相关的 gem :
* jquery-rails (4.0.4)
* rails (4.2.3)
* aws-sdk (2.1.13)
* aws-sdk-core (2.1.13)
* aws-sdk-resources (2.1.13)
还使用jquery.fileupload.js 5.42.3
我不知道如何让它发挥作用。
提前致谢!
最佳答案
我找到了解决方案。
我在前端捕获的后端生成的表单数据:
upload_form_data = '<%= escape_javascript(@presigned_post.fields.to_json.html_safe) %>'
必须从 JSON 字符串转换为 JavaScript 对象:
upload_form_data_obj = JSON.parse(upload_form_data);
显然,$.fileupload
函数需要一个 formData 对象,而不是字符串。
完成此更改后,所需的表单数据将包含在到 S3 的 POST 中,并且成功。
这是有效的 JavaScript 代码:
$(function() {
var $form = $('form.direct_upload'),
upload_url,
upload_form_data,
upload_form_data_obj;
if ($form.length) {
upload_url = '<%= escape_javascript(@presigned_post.url) %>'
upload_form_data = '<%= escape_javascript(@presigned_post.fields.to_json.html_safe) %>';
upload_form_data_obj = JSON.parse(upload_form_data);
console.log('URL: ', upload_url);
console.log('Form data: ', upload_form_data_obj);
$form.find('input[type=file]').each(function(index, input) {
var $file_field = $(input);
$file_field.fileupload({
fileInput: $file_field,
url: upload_url,
type: 'POST',
autoUpload: false,
formData: upload_form_data_obj, // needed to be an object, not a string
paramName: 'file',
dataType: 'JSON',
add: function(e, data) {
console.log('add callback fired.');
$form.submit(function(e) {
e.preventDefault();
console.log('form submitted.');
console.log(data);
data.submit();
});
},
start: function(e) {
console.log('start callback fired');
},
done: function(e, data) {
console.log('done callback fired');
},
fail: function(e, data) {
console.log('fail callback fired');
console.log(e);
console.log(data);
}
});
});
}
});
关于javascript - 使用jquery.fileupload直接上传到amazon S3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31904841/
我想知道 Amazon CloudSearch 和 Kendra 之间的主要区别是什么?为什么同一家公司的产品有两种不同的工具相互竞争?两者看起来都一样,我不确定功能有何不同。它是如何相互区分的。 A
我在一家小型电子商务网站工作,我们希望迁移到所有 Amazon 托管服务,但我不确定 RDS 和 SimpleDB 的确切区别。 RDS可以用MySQL,SimpleDB不行吗? 最佳答案 RDS 基
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 7年前关闭。 Improve t
任何人都知道如何 ELB如果我注册多个 EC2 将分发请求不同大小的实例。说一 m1.medium , 一 m1.large和一个 m1.xlarge . 如果我注册EC2会不会不一样相同大小的实例?
Amazon EventBridge 使开发人员能够将第 3 方事件驱动的应用程序与 Amazon 服务连接起来。 Amazon AppFlow 还提供与第 3 方应用程序的事件驱动集成。 对于事件驱
我想通过电子邮件或短信向特定用户(只有一个)发送验证码。我已经通过 Amazon SES 成功地做到了。但我没有尝试通过Amazon SMS然而。我发现自己陷入了调查的兔子洞AWS Pinpoint
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 6年前关闭。 Improve thi
我想使用 Amazon Glacier 镜像 S3 存储桶。 Glacier FAQ状态: Amazon S3 now provides a new storage option that enabl
我正在尝试在 Amazon RDS 上托管数据库,而数据库将存储信息的实际内容(视频)将托管在 Amazon S3 上。我对这个过程有一些疑问,希望有人能帮助我。 Amazon RDS 上托管的数
我刚刚开始使用 AWS EC2。我知道 EC2 就像一台远程计算机,我几乎可以在其中完成我想做的所有事情。后来我知道了ECS。我知道它使用 Docker,但我对这两者之间的关系感到困惑。 ECS 只是
什么时候我会使用 SNS 和 SQS,为什么它们总是耦合在一起? 最佳答案 SNS是一个分布式发布-订阅系统。当发布者将消息发送到 SNS 时,消息就会被推送给订阅者。 SQS是分布式排队系统。消息不
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a software
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
我计划在 amazon EC2 中拥有一个多服务器架构,其中服务器需要相互通信。这些服务器需要位于不同的亚马逊地区(不同的数据中心)。我可以只使用亚马逊ec2的内部网络吗?有哪些安全问题?我是否应该在
我在帐户 B 中有 S3 存储桶“跨存储桶”。现在我希望帐户 A 中存在的 EC2 访问帐户 B 中的此存储桶“跨存储桶”。 我需要使用 IAM 角色来实现此目的,因为我们不允许创建用户。 我已使用以
我有使用 Backbone.js 构建的单页应用程序。 我在 Amazon S3 上托管应用程序(应用程序仅包含静态文件)。 我使用 CloudFront 作为 Bucket CDN。 应用程序通过
我可以连接到 ElastiCache来自 EC2 实例 的 VPC 中的 Redis 实例。但我想知道是否有办法连接到 Amazon EC2 实例之外的 ElastiCache Redis 节点,例如
我有几个微实例可以正常工作数周。两者都在运行WordPress博客。在过去的24小时内,其中一个已经停止。即使重新启动,我也无法插入。另一个实例工作正常。 ssh: connect to host e
我尝试了以下方法: SELECT * FROM generate_series(2,4); generate_series ----------------- 2
如何使用PHP API将包含子文件夹和文件的文件夹复制/复制到S3存储桶中的另一个目录中? $s3->copy_object仅复制文件夹,而不复制其中的文件和子文件夹。 我是否必须使用$s3->lis
我是一名优秀的程序员,十分优秀!