活动存储public_url不返回密钥/文件名扩展名

问题描述

在此PR中将公用选项添加到了Active Storage:https://github.com/rails/rails/pull/36729
他在其中清楚地说:“在公共存储桶中,目录结构为/ [key] / [filename]”

这是有道理的,而这正是我想要的。我希望能够(例如)通过电子邮件链接发送给某人,并允许他们下载文件。所以我需要filename.extension。但是,当我启动Rails 6.1应用程序时,上传到我的存储桶的文件名后面没有文件名。 这些文件确实出现在我的存储桶中,但仅作为密钥。不是密钥/文件名。

amazon:
  service: S3
  access_key_id: <%= Rails.application.credentials.dig(:aws,:access_key_id) %>
  secret_access_key: <%= Rails.application.credentials.dig(:aws,:secret_access_key) %>
  region: us-east-1
  bucket: mybucket
  public: true

上传正常。文件上传显示在我的存储桶中。但是在视图<%= @user.avatar.url %>中返回https://s3.amazonaws.com/mybucket/g3ci2umbfj6wkxyggx7arhekxfib,我想要返回https://s3.amazonaws.com/mybucket/g3ci2umbfj6wkxyggx7arhekxfib/myfile.png 这真的让我很烦,因为在PR中作者明确指出公共文件另存为key / filename.extension

所以问题来了:在Rails 6.1中,url方法是否将文件名作为路径的一部分返回。如果不是的话,作者为什么这么说呢?还有没有比修补key更好的方法了?

解决方法

TLDR:

= link_to @user.avatar.filename,rails_blob_path(@user.avatar,disposition: "course.avatar"),target: :_blank

会为您提供一个下载链接,例如https://corsego-production.s3.eu-central-1.amazonaws.com/3gbpl68kckpkyrbjoslsl254th0u?response-content-disposition=inline&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEGgaCmV1LBuuKkri8zL3ohM4h9STzhTsnavAgulrcpBavL0POXg%3D%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20201002T170820Z&X-Amz-SignedHeaders=host&X-Amz-Expires=300&X-Amz-Credential=ASIA5RINJ20201002%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Signature=0a205d713ebaa9d3ca9d62


@user.avatar.url不应该返回任何东西!

@user.avatar应该返回类似#<ActiveStorage::Attached::One:0x00007f15986ee4c0>

的内容

使用Active Storage创建附件时,有关附件的以下字段会自动填充并另存为active_storage_blobs

  create_table "active_storage_blobs",force: :cascade do |t|
    t.string "key",null: false
    t.string "filename",null: false
    t.string "content_type"
    t.text "metadata"
    t.bigint "byte_size",null: false
    t.string "checksum",null: false
    t.datetime "created_at",null: false
    t.index ["key"],name: "index_active_storage_blobs_on_key",unique: true
  end

比方说,您上传具有活动存储空间的图像。上表将通过以下方式填充:

Id: 1
Key: sy2y1ytw7zob6mwtnwc1552cdp5l
Filename: Screenshot 2020-10-02 125405.png
Content_type: image/png
Metadata: {"identified"=>true,"analyzed"=>true}
Byte_size: 1550
Checksum: mGPerbRMj6LXbPKhqKd4bA

要将用户头像显示为图像,必须调用= image_tag @user.avatar

= rails_blob_url(@user.avatar)将为您提供类似https://example.com/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--5fb10a9c8e9f2c4e7099eee21c1dc2ff0343c210/Screenshot%202020-10-02%20125405.png

的信息

= @user.avatar将为您提供类似#<ActiveStorage::Attached::One:0x00007f1589293dd0>

的信息

= url_for(@user.avatar)将为您提供类似/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--5fb10a9c8e9f2c4e7099eee21c1dc2ff0343c210/Screenshot%202020-10-02%20125405.png

的信息

由active_storage创建的迁移中的第二个表是:

  create_table "active_storage_attachments",force: :cascade do |t|
    t.string "name",null: false
    t.string "record_type",null: false
    t.bigint "record_id",null: false
    t.bigint "blob_id",null: false
    t.index ["blob_id"],name: "index_active_storage_attachments_on_blob_id"
    t.index ["record_type","record_id","name","blob_id"],name: "index_active_storage_attachments_uniqueness",unique: true
  end

基本上,它将blob与应用程序中的特定记录连接起来(基本上,avatarblob@userrecord,它们通过active_storage_attachments表。

因此,您还可以在@ user.avatar方法上运行以下命令:

@user.avatar.name #Avatar
@user.avatar.record_type #User
@user.avatar.record_id #2 (user id)
@user.avatar.blob_id #1 (blob id)

enter image description here

现在,以下是存储在AWS S3上的上述文件的示例URL: https://corsego-production.s3.eu-central-1.amazonaws.com/3gbpl68kckpkyrbjoslsl254th0u?response-content-disposition=inline&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEGgaCmRzBFAiBSJ2QIEqs1opj%2BuCR74CDMt67ueDTTQIhAOJGGy2wfmxmGUwpQe9cyc84ZhUhuWKHdVgTUctbtGrVKdinkpg0w7OikcyNYpnbq%2FefcTmEgRvIlPO%2B0itFxUr8mKUvnDYSuKkri8zL3ohM4h9STzhTsnavAgulrcpBavL0POXg%3D%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20201002T170820Z&X-Amz-SignedHeaders=host&X-Amz-Expires=300&X-Amz-Credential=ASIA5RINJLY2F20201002%2Feu-central-2%2Fs3%2Faws4_request&X-Amz-Signature=0a205d713ebaaa339ad4ee09db9dfe16986e69d3ca9d62

查看网址如何包含秘密令牌和有效时间?建议不要对文件使用永久的URL。

P.S。将AWS S3连接到您的应用程序时,请不要忘记添加CORS configurationenter image description here

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...