Rails对接EsignGenie实现PDF下载后文件损坏问题排查
问题根因与解决方案
核心问题
- 你在
EsignGenie.download_pdf方法中将PDF原始二进制数据做了Base64编码后直接返回给send_data,而send_data默认会将接收到的内容直接作为响应体发送给浏览器。此时浏览器拿到的是Base64编码的文本内容,并非标准PDF二进制流,所以打开时会提示文档损坏。 - 缺少API请求失败的异常兜底处理:如果调用eSignGenie接口报错,
response变量为nil,后续调用response.file会直接抛出空指针异常,也会导致返回内容异常。
修复方案
直接返回PDF原始二进制内容即可,无需做Base64编码,修改后的代码如下:
1. 修正Module代码
module EsignGenie def self.download_pdf(folder_id) url = "https://www.esigngenie.com/esign/api/folders/download?folderId=#{folder_id}" begin response = RestClient::Request.execute(method: :get, url: url, raw_response: true, headers: {Authorization: "Bearer #{ENV['ESIGNGENIE_AUTH']}"} ) # 直接返回原始二进制内容,不要做Base64编码 File.open(response.file).read rescue => e Sentry.capture_exception(e) # 异常时返回nil,后续控制器做拦截 nil end end end
2. 控制器增加异常兜底(可选,推荐添加)
增加请求失败的判断,避免接口异常时返回无效内容:
class SignedDocumentsController < ApplicationController before_action :authenticate_user! before_action :authorize_manager def download_pdf doc = SignedDocument.find(params[:id]) data = EsignGenie.download_pdf(doc.folder_id) if data.blank? flash[:alert] = "PDF下载失败,请稍后重试" redirect_back fallback_location: signed_documents_path return end send_data(data, type: "application/pdf", disposition: "attachment", filename: "#{doc.external_document&.name || doc.folder_id}.pdf") end end
验证方法
修改后先在本地调试EsignGenie.download_pdf方法,将返回的内容写入本地.pdf文件,确认可以正常打开后再测试页面下载流程即可。
内容的提问来源于stack exchange,提问作者Jeremy Thomas
相关产品推荐
相关产品推荐

