
在 ruby on rails 开发中,有时我们需要在网页中直接显示 pdf 内容,而不是仅仅提供下载链接。许多初学者可能会混淆“发送 pdf 文件”和“在 html 页面中嵌入 pdf”这两个概念。例如,使用 send_file 方法(如 send_file(menu_pdf, filename: 'menulq2.pdf', disposition: 'inline', type: 'application/pdf'))主要用于从服务器向客户端发送文件,并指示浏览器如何处理(例如,disposition: 'inline' 尝试在浏览器中打开,但并非直接嵌入到 当前 html 视图中)。要将 pdf 真正嵌入到 html 页面中,我们需要利用 html 自身的元素。
核心方法:使用 HTML <embed> 标签
在 HTML 中,最直接且广泛支持的嵌入 PDF 文件的方法是使用 <embed> 标签。这个标签允许将外部内容(如 PDF、视频、音频等)嵌入到文档中。
基本语法:
<embed src="你的PDF文件路径" width="宽度" height="高度" type="application/pdf">
- src: 指定 PDF 文件的 URL 或路径。
- width: 指定嵌入内容的宽度。
- height: 指定嵌入内容的高度。
- type: 必须设置为 application/pdf,告知浏览器这是一个 PDF 文件。
接下来,我们将探讨两种在 Rails 应用中获取这个 src 路径的具体策略。
方案一:结合 Rails Asset Pipeline 和 asset_path 助手
Rails 的 Asset Pipeline 是管理前端静态资源(如 CSS、JavaScript、图片、字体等)的强大工具。如果你的 PDF 文件被视为应用程序的静态资源,并且位于 app/assets 目录下(例如 app/assets/files/menulq2.pdf),那么使用 asset_path 助手是最佳实践。
优点:
- 文件名哈希处理: Asset Pipeline 在预编译时会为静态文件生成一个唯一的哈希值并添加到文件名中(例如 menulq2-60aa4fdc5cea14baf5400fba1abf4f2a46a5166bad4772b1effe341570f07de9.pdf)。asset_path 助手会自动处理这个哈希,你只需提供原始文件名即可。这有助于缓存管理和避免浏览器缓存旧版本文件的问题。
- 路径抽象: 无论资源最终部署在哪里(CDN、子目录等),asset_path 都能生成正确的 URL。
实现步骤:
- 放置 PDF 文件: 将你的 PDF 文件放置在 app/assets 目录下的某个子目录中,例如 app/assets/files/ 或 app/assets/pdfs/。
- 在视图中使用 asset_path: 在你的 ERB 视图文件中,使用 asset_path 助手来生成 PDF 文件的 URL。
示例代码:
假设你的 PDF 文件位于 app/assets/files/menulq2.pdf。
<!-- app/views/your_controller/your_action.html.erb -->
<h1>我们的菜单</h1>
<div class="pdf-container">
<embed src="<%= asset_path('menulq2.pdf') %>"
width="100%"
height="600px"
type="application/pdf">
</div>
<p>如果PDF无法显示,请点击 <a href="<%= asset_path('menulq2.pdf') %>" target="_blank">这里下载</a>。</p>请注意,asset_path 只需要文件的原始文件名。Rails 会根据配置在 app/assets 及其子目录中查找该文件。
方案二:直接引用静态文件路径
如果你不希望将 PDF 文件纳入 Asset Pipeline 管理,或者你的 PDF 文件位于 public 目录下,你可以直接在 <embed> 标签中使用硬编码的路径。
适用场景:
- 文件不需要版本控制或哈希处理。
- 文件直接放在 public 目录下,作为静态文件服务。
- Asset Pipeline 未启用或不适用于该文件。
实现步骤:
- 放置 PDF 文件: 将你的 PDF 文件放置在 public 目录下的某个子目录中,例如 public/files/menulq2.pdf。
- 在视图中直接引用路径:
示例代码:
假设你的 PDF 文件位于 public/files/menulq2.pdf。
<!-- app/views/your_controller/your_action.html.erb -->
<h1>我们的菜单</h1>
<div class="pdf-container">
<embed src="/files/menulq2.pdf"
width="100%"
height="600px"
type="application/pdf">
</div>
<p>如果PDF无法显示,请点击 <a href="/files/menulq2.pdf" target="_blank">这里下载</a>。</p>重要配置:启用静态文件服务
为了让 Rails 能够服务 public 目录下的静态文件,你需要在开发环境或生产环境的配置文件中确保静态文件服务已启用。
-
Rails 4 及更早版本: 在 config/environments/development.rb 或 config/environments/production.rb 中设置:
config.serve_static_files = true
-
Rails 5 及更高版本: 在 config/environments/development.rb 或 config/environments/production.rb 中设置:
config.public_file_server.enabled = true
在生产环境中,通常建议使用 Nginx 或 Apache 等 Web 服务器来直接服务静态文件,而不是让 Rails 应用处理。但如果你的部署环境没有专门的静态文件服务器,启用 Rails 的静态文件服务是必要的。
注意事项与最佳实践
- 用户体验: 嵌入大型 PDF 文件可能会影响页面加载速度。考虑提供一个下载链接作为备选方案,或者在 PDF 加载前显示加载指示器。
- 兼容性: 尽管 <embed> 标签被广泛支持,但并非所有浏览器和设备都能完美显示所有 PDF。例如,移动设备上的某些浏览器可能需要外部 PDF 阅读器应用。
- 响应式设计: 直接设置 width="100%" 和 height="600px" 可能不适用于所有屏幕尺寸。考虑使用 CSS 媒体查询或 JavaScript 来动态调整 <embed> 标签的尺寸,以适应不同的设备。
- 安全性: 如果嵌入的 PDF 文件来自用户上传,请务必进行内容验证和安全扫描,以防止恶意文件攻击。
- 替代方案: 如果 <embed> 标签无法满足需求,可以考虑使用第三方 JavaScript 库(如 PDF.js)来渲染 PDF,这提供了更强的控制力和跨浏览器兼容性。
总结
在 Rails 应用中嵌入 PDF 文件主要依赖于 HTML 的 <embed> 标签。开发者可以根据 PDF 文件的管理方式(是否通过 Asset Pipeline)选择使用 asset_path 助手或直接硬编码路径。对于通过 Asset Pipeline 管理的资源,asset_path 是推荐的选择,它能更好地处理文件版本和缓存。而对于简单的静态文件,直接引用路径并确保 Rails 静态文件服务已启用则更为直接。在实施过程中,务必关注用户体验、兼容性和安全性,以提供最佳的 PDF 内容展示。










