如何处理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
- Ubuntu/Debian:
原理说明
- 重写
previewable?方法,在原有ActiveStorage的判断基础上,额外检测PDF是否加密 - 通过下载Blob到本地临时文件,兼容本地存储和云存储(如S3)的场景
- 同时支持MiniMagick和pdfinfo两种检测方式,适配不同的处理器配置
- 任何读取异常都直接标记为不可预览,避免抛出
PreviewError
内容的提问来源于stack exchange,提问作者Mark Robinson
相关产品推荐
相关产品推荐

