使用 Uppy trough Shrine return 405 Method Not Allowed 上传图片
Uploading image with Uppy trough Shrine return 405 Method Not Allowed
我正在尝试使用 Ruby On Rails 作为我的后端,以及像 ReactOnRails 和 Shrine 这样的宝石,此外,我使用包 Uppy 将图像上传到 AWS S3
到目前为止一切正常,直到我尝试通过 Uppy 上传图像,这应该通过后端传输 AWS 凭证,所以我不会从前端公开我的密钥。
React 组件片段
.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 上传文件时,我不知道如何解决这个问题。
Shrine 的预签名端点响应 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
并为您完成所有的抓取工作:
uppy.use(AwsS3, {
companionUrl: '/',
...
})
我正在尝试使用 Ruby On Rails 作为我的后端,以及像 ReactOnRails 和 Shrine 这样的宝石,此外,我使用包 Uppy 将图像上传到 AWS S3
到目前为止一切正常,直到我尝试通过 Uppy 上传图像,这应该通过后端传输 AWS 凭证,所以我不会从前端公开我的密钥。
React 组件片段
.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 上传文件时,我不知道如何解决这个问题。
Shrine 的预签名端点响应 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
并为您完成所有的抓取工作:
uppy.use(AwsS3, {
companionUrl: '/',
...
})