我正在尝试将Ruby On Rails用作后端,并使用ReactOnRails和Shrine之类的宝石,此外,我使用软件包Uppy将图像上传到AWS S3
到目前为止,一切正常,直到我尝试通过Uppy上传映像为止,该映像应该通过后端传输AWS凭证,因此我不会从前端公开我的秘密密钥。
React Component的代码段
.use(AwsS3, {
limit: 5,
// serverUrl: 'https://uppy-companion.my-app.com/',
strings: {
preparingUpload: 'Preparing upload...'
},
getUploadParameters(file) {
return fetch('/presign?filename=' + file.name, {
method: 'post',
// Send and receive JSON.
headers: {
accept: 'application/json',
'content-type': 'application/json'
},
body: JSON.stringify({
filename: file.name,
contentType: file.type
})
}).then((response) => {
// Parse the JSON response.
return response.json()
}).then((data) => {
// Return an object in the correct shape.
return {
method: data.method,
url: data.url,
fields: data.fields
}
}).catch((error) => console.log(error))
}
});
我的路线是
mount Shrine.presign_endpoint(:cache) => '/presign'
最后是我的shrine.rb文件
require 'shrine'
if Rails.env.production?
require 'shrine/storage/s3'
s3_options = {
access_key_id: Rails.application.credentials.aws[:s3_access_key_id],
secret_access_key: Rails.application.credentials.aws[:s3_secret_access_key],
region: Rails.application.credentials.aws[:s3_region],
bucket: Rails.application.credentials.aws[:s3_bucket]
}
Shrine.storages = {
cache: Shrine::Storage::S3.new(prefix: 'cache', **s3_options),
store: Shrine::Storage::S3.new(prefix: "store", **s3_options)
}
else
require 'shrine/storage/file_system'
Shrine.storages = {
cache: Shrine::Storage::FileSystem.new('public', prefix: 'uploads/cache'),
store: Shrine::Storage::FileSystem.new('public', prefix: 'uploads')
}
end
Shrine.plugin :activerecord
Shrine.plugin :backgrounding
Shrine.plugin :logging
Shrine.plugin :determine_mime_type
Shrine.plugin :cached_attachment_data
Shrine.plugin :restore_cached_data
#TODO: docs
Shrine.plugin :presign_endpoint if Rails.env.production?
Shrine.plugin :upload_endpoint if !Rails.env.production?
Shrine::Attacher.promote { |data| PromoteJob.perform_async(data) }
Shrine::Attacher.delete { |data| DeleteJob.perform_async(data) }
我的AWS S3 Cros配置
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
<AllowedHeader>x-amz-date</AllowedHeader>
<AllowedHeader>x-amz-content-sha256</AllowedHeader>
<AllowedHeader>content-type</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
</CORSRule>
</CORSConfiguration>
当我通过uppy.js上传文件时,我只是想不通如何解决此问题。
答案 0 :(得分:1)
神社的预设端点响应GET
而不是POST
的请求,因此您需要这样做
getUploadParameters(file) {
return fetch('/presign?filename=' + file.name, {
method: 'get',
...
顺便说一句,如果将前缀端点安装在/s3/params
上:
Rails.application.routes.draw do
mount Shrine.presign_endpoint(:cache) => "/s3/params"
end
您不需要任何fetch()
逻辑,只需将Uppy指向您的应用,它将自动使用/s3/params
并为您完成所有提取工作:
.use(AwsS3, {
serverUrl: '/',
...
})