1

我正在使用神社直接上传到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 以允许所有请求,如下所示

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策略中缺少错误提示。但是,如果是这样,我该如何添加呢?

4

2 回答 2

2

似乎 DigitalOcean Spaces 现在需要包含contentType条件的预签名策略。presign 策略是在 presign 端点中生成的,因此您可以: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)
于 2018-02-07T10:08:57.477 回答
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. 所以我们必须像这样手动指定以使其与空格一起使用。

于 2018-02-06T11:25:46.650 回答