You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何处理ActiveStorage::PreviewError:密码保护PDF预览失败问题

解决Rails 6.1 ActiveStorage带密码PDF预览报错问题

要让带密码保护的PDF返回previewable? == false而非触发ActiveStorage::PreviewError,你需要扩展ActiveStorage的Blob类,在原有的预览判断逻辑中加入密码检测:

步骤1:添加Blob扩展模块

在app/models/concerns/active_storage_blob_extensions.rb中创建扩展代码:

module ActiveStorageBlobExtensions
  # 重写预览判断方法,排除加密PDF
  def previewable?
    super && !password_protected_pdf?
  end

  private

  def password_protected_pdf?
    return false unless content_type == "application/pdf"

    # 下载Blob到本地临时文件,兼容本地/云存储
    tempfile = download_blob_to_tempfile
    check_pdf_encryption(tempfile.path)
  rescue StandardError
    # 任何读取失败都视为加密/不可预览
    true
  ensure
    tempfile&.close!
  end

  def check_pdf_encryption(file_path)
    if ActiveStorage.variant_processor == :mini_magick
      # 用MiniMagick检测PDF加密属性
      MiniMagick::Image.open(file_path) do |img|
        img.data.dig("Properties", "PDF:Encrypted") == "yes"
      end
    else
      # 用Poppler的pdfinfo命令检测(需服务器安装poppler-utils)
      result = `pdfinfo "#{file_path}" 2>&1`
      result.include?("Encrypted: yes")
    end
  end
end

步骤2:加载扩展

在config/initializers/active_storage.rb中添加以下代码,确保扩展被加载:

Rails.application.config.to_prepare do
  ActiveStorage::Blob.include(ActiveStorageBlobExtensions)
end

依赖说明

  • 确保Gemfile中已添加gem 'mini_magick',执行bundle install
  • 服务器需安装依赖工具:
    • Ubuntu/Debian:sudo apt-get install imagemagick poppler-utils
    • macOS:brew install imagemagick poppler

原理说明

  • 重写previewable?方法,在原有ActiveStorage的判断基础上,额外检测PDF是否加密
  • 通过下载Blob到本地临时文件,兼容本地存储和云存储(如S3)的场景
  • 同时支持MiniMagick和pdfinfo两种检测方式,适配不同的处理器配置
  • 任何读取异常都直接标记为不可预览,避免抛出PreviewError

内容的提问来源于stack exchange,提问作者Mark Robinson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:42:13