为什么内部PDF在embed/iframe中直接下载而非内嵌预览?
问题背景
我们有一个内部网站,其中包含多个指向托管在webserver上的PDF文档的链接。如果我打开Chrome Dev-Tools(F12),检查链接并添加指向同一份PDF文档的embed标签,文件会直接下载而非在页面中展示。我尝试过embed和iframe两种标签,均存在相同问题。
原始代码
<a id="id2239" href="http://example.com:8080/client/attachment/filename.pdf" class="act01">filename.pdf</a>
原始页面截图:
期望正常运行的代码
<a id="id2239" href="http://example.com:8080/client/attachment/filename.pdf" class="act01">filename.pdf</a> <div class="fgh"><embed id="fgh" src="http://example.com:8080/client/attachment/filename.pdf" type="application/pdf" width="400" height="400"></div>
修改后页面截图:
实际运行后PDF被直接下载,embed区域仅显示空白:
可正常运行的对照代码
替换为外部公开PDF后可正常内嵌展示,无自动下载问题:
<a id="id2239" href="http://example.com:8080/client/attachment/filename.pdf" class="act01">filename.pdf</a> <div class="fgh"><embed id="fgh" src="http://infolab.stanford.edu/pub/papers/google.pdf" type="application/pdf" width="400" height="400"></div>
对照代码运行截图:
待解答问题
- 两个示例的表现为什么存在差异?为什么内部文档直接下载,外部文档可在页面内嵌展示?
- 如何让我们自身webserver上的文件也支持内嵌预览?
补充信息
内部PDF文档的响应头截图如下:
回答
问题1 差异原因
两者的核心区别是服务端返回的Content-Disposition响应头配置不同:
- 内部webserver返回PDF时,响应头的
Content-Disposition设置为attachment,浏览器识别到这个配置后,无论前端用embed还是iframe加载,都会直接触发文件下载行为,不会尝试内嵌渲染。 - 外部公开的PDF服务端返回的
Content-Disposition设置为inline,该配置会告知浏览器优先在页面内直接渲染内容,无需下载。
此外如果响应头的Content-Type被错误设置为application/octet-stream而非application/pdf,也会触发浏览器的默认下载行为。
问题2 解决方案
只需要修改内部webserver的配置,调整PDF文件的响应头参数即可:
- 首先确保PDF文件的
Content-Type响应头正确设置为application/pdf - 将
Content-Disposition响应头的值从attachment改为inline
常见服务端配置示例:
- Nginx:在配置文件的对应location块中添加以下配置
location ~* \.pdf$ { add_header Content-Type application/pdf; add_header Content-Disposition inline; } - Apache:在
.htaccess文件中添加以下配置<FilesMatch "\.pdf$"> Header set Content-Type application/pdf Header set Content-Disposition inline </FilesMatch> - 后端代码动态返回PDF:如果PDF是通过业务接口动态返回的,在返回响应时手动设置对应响应头即可,以Java SpringBoot为例:
response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "inline; filename=filename.pdf");
配置修改后清理浏览器缓存重试,即可正常在embed/iframe中内嵌预览PDF。
内容的提问来源于stack exchange,提问作者patchie
相关产品推荐
相关产品推荐

