如何在Rails中通过HTTP POST渲染PDF文件
解决Rails作为中间件返回Java服务生成的PDF问题
我来帮你搞定这个问题!你遇到的核心问题是没有正确获取到Java服务返回的PDF二进制数据,直接返回了EventMachine HTTP客户端的对象,而不是它的响应内容。下面是一步步的解决方案:
首先:确保拿到真正的PDF二进制数据
你用的应该是em-http-request这类基于EventMachine的异步HTTP客户端,这类工具返回的EventMachine::HttpClient对象只是请求的句柄,不是响应内容。必须在异步回调里获取响应体:
# 示例:用em-http-request发起异步请求 http = EventMachine::HttpRequest.new('http://你的Java服务地址/pdf接口').post( body: params.to_json, headers: {'Content-Type' => 'application/json'} ) http.callback do # 这里才是真正拿到Java返回的PDF二进制数据的地方 pdf_binary = http.response # 接下来把pdf_binary返回给客户端 end http.errback do # 处理请求失败的情况,比如返回错误页面 render plain: 'PDF生成失败', status: 500 end
不过这里要注意:Rails控制器默认是同步处理请求的,用异步EventMachine的话,需要确保控制器等待请求完成再响应。如果觉得异步麻烦,换成同步HTTP客户端会更简单,比如用Ruby自带的Net::HTTP或者Faraday的同步适配器:
# 示例:用Net::HTTP同步请求Java服务 require 'net/http' def generate_pdf uri = URI('http://你的Java服务地址/pdf接口') payload = params.to_json headers = {'Content-Type' => 'application/json'} # 同步发起POST请求,直接拿到响应 response = Net::HTTP.post(uri, payload, headers) pdf_binary = response.body # 把PDF返回给前端 render_pdf(pdf_binary) end
然后:正确渲染PDF给客户端
拿到二进制数据后,不能用render plain:(它会把二进制当成文本处理,导致乱码或损坏),必须用render body:同时设置正确的响应头,告诉浏览器这是PDF文件:
def render_pdf(pdf_binary) render( body: pdf_binary, content_type: 'application/pdf', # 必须设置这个,浏览器才会识别为PDF disposition: 'inline' # 可选:inline是在浏览器内打开,attachment是触发下载 ) end
常见坑点提醒
- 如果Java服务返回的是Base64编码的PDF字符串,记得先解码:
pdf_binary = Base64.decode64(response.body) - 不要直接返回
EventMachine::HttpClient对象,一定要提取它的response属性(异步回调里)或者同步客户端的body属性 - 确保请求的Content-Type和Java服务要求的一致(比如如果Java服务需要form-data,就不要传JSON)
内容的提问来源于stack exchange,提问作者Felipe Faria - Disparter
相关产品推荐
相关产品推荐

