使用谷歌云存储强制在活动存储对象上进行内容配置

问题描述 投票:0回答:1

预期结果

即使文件可以像图像一样在浏览器中显示,也强制下载文件。

问题

我在使用

rails_blob_url(file, disposition: 'attachment')
file.url(disposition: 'attachment')
时遇到问题,这可能是相同的?文件的响应头始终是
content-disposition: inline; filename="image.png"; filename*=UTF-8''image.png

在我的本地开发机器(使用本地文件存储)上,它对于图像也运行得很好 - 所有内容都会被强制下载。在我使用谷歌云存储的暂存环境中,似乎配置附件被忽略了。 GCS 文件上没有设置元数据配置,因此文档指出它应该使用提供的查询字符串(响应内容配置和响应内容类型)。所有文件都是私有的,因此我们使用signed_url。

我创建了一种调试方法 - 基本上使用与主动存储内部相同的方法..

def download_url
  disposition = "attachment"
  service = @file.service
  expires_in = 300

  if service.name == :google
    gcs_config = Rails.application.config.active_storage.service_configurations['google']
    storage = Google::Cloud::Storage.new(
      project_id: gcs_config['project'],
      credentials: gcs_config['credentials']
    )
    bucket = storage.bucket(gcs_config['bucket'])
    blob = bucket.file(@file.key, skip_lookup: true)

    content_disposition_formatted = ActionDispatch::Http::ContentDisposition.format(disposition: disposition, filename: @file.filename.sanitized)
    args = {
      expires: expires_in,
      query: {
        "response-content-disposition" => content_disposition_formatted,
        "response-content-type" => @file.content_type
      }
    }

    logger.info "X"*80
    logger.info @file.filename
    logger.info "X"*80
    logger.info args.inspect
    logger.info "X"*80

    blob.signed_url(**args)
  else
    rails_blob_url(@file, disposition: disposition, expires_in: expires_in)
  end
end

有什么想法如何强制执行此操作吗?应该是有可能的——对吧?!

ruby-on-rails google-cloud-storage rails-activestorage
1个回答
0
投票

使用直接上传时,gcs 存在 activestorage bug

activestorage/lib/active_storage/service/s3_service.rb#headers_for_direct_upload
。它将内容处置元数据设置为内联,目前获取内容处置工作的查询参数的唯一方法是清除内容处置元数据。

这是清除它的丛林方法:

def clear_content_disposition
  return unless file.service.name == :google

  gcs_config = Rails.application.config.active_storage.service_configurations['google']
  storage = Google::Cloud::Storage.new(
    project_id: gcs_config['project'],
    credentials: gcs_config['credentials']
  )
  bucket = storage.bucket(gcs_config['bucket'])
  blob = bucket.file(file.key, skip_lookup: true)
  blob.content_disposition = nil
end
© www.soinside.com 2019 - 2024. All rights reserved.