我正在使用神社直接上传到aws-s3
水桶并且工作正常。现在我想使用DigitalOcean spaces
代替。所以我更改了一些神社的设置,如下所示(仅更改了与空格相关的env
变量)。
require "shrine"
require "shrine/storage/s3"
s3_options = {
access_key_id: ENV["SPACES_ACCESS_KEY_ID"],
secret_access_key: ENV["SPACES_SECRET_ACCESS_KEY"],
region: ENV["SPACES_REGION"],
bucket: ENV["SPACES_BUCKET"],
endpoint: ENV["SPACES_ENDPOINT"]
}
Shrine.storages = {
cache: Shrine::Storage::S3.new(prefix: "cache", upload_options: {acl: "public-read"}, **s3_options),
store: Shrine::Storage::S3.new(prefix: "store", upload_options: {acl: "public-read"}, **s3_options),
}
Shrine.plugin :activerecord
Shrine.plugin :presign_endpoint
Shrine.plugin :restore_cached_data
Shrine.plugin :backgrounding
Shrine::Attacher.promote {|data| UploadJob.perform_async(data)}
Shrine::Attacher.delete {|data| DeleteJob.perform_async(data)}
我还在空格中添加了cors以允许所有请求,如下面的
但是当我上传时,我收到了这个错误。
<Error><Code>AccessDenied</Code><Message>Policy missing condition: Content-Type</Message><BucketName>testing-dev</BucketName><RequestId>tx0000000036366363370-3663t37373-33883-sgp1a</RequestId><HostId>349494-sgp1a-sgp</HostId></Error>
这可能是什么问题?我可以看到政策中缺少告诉content-type
的错误。但是,如果是这样的话我该如何补充呢?
答案 0 :(得分:2)
现在,DigitalOcean Spaces似乎要求预设政策包含contentType
条件。预设策略在预设端点中生成,因此您可以根据:content_type
查询参数告诉它添加filename
:
Shrine.plugin :presign_endpoint, presign_options: -> (request) do
filename = request.params["filename"]
extension = File.extname(filename)
content_type = Rack::Mime.mime_type(extension)
{ content_type: content_type }
end
这应该始终显示:content_type
,因为如果filename
没有扩展程序或扩展程序无法识别,Rack::Mime.mime_type
将返回application/octet-stream
,这是内容类型S3无论如何都默认分配给对象。
发送预设请求时,请确保在客户端传递filename
查询参数。例如。使用window.fetch
它将是:
fetch('/presign?filename=' + file.name)
答案 1 :(得分:0)
我发现解决方案是手动添加contentType
。
所以我像这样更新了
Shrine.storages = {
cache: Shrine::Storage::S3.new(prefix: "cache", upload_options: {acl: "public-read", content_type: "png/jpeg"}, **s3_options),
store: Shrine::Storage::S3.new(prefix: "store", upload_options: {acl: "public-read", content_type: "png/jpeg"}, **s3_options),
}
我不知道这是最好的方法,因为它将根据contentType
自动设置mime type
,并在上传到亚马逊s3
时正常工作。但不知怎的,这与digitalocean
无效。因此我们必须手动指定这样才能使用空格。