跨域PDF打印问题:可控双域名下JS调用print遭拦截的解决方法
问题描述
设域名A为Domain.com,域名B为仅含IP地址的无HTTPS站点,PDF文件存储于域名B,示例地址为http://8.8.8.8/my.pdf。
我通过代码var printWindow = window.open( url, 'Print', 'left=200, top=200, width=950, height=700, toolbar=0, resizable=1');打开该PDF,但调用printWindow.print();时出现错误:Failed to read a named property 'print' from 'Window': Blocked a frame with origin "DomainA" from accessing a cross-origin frame。
我拥有两个域名的完全控制权,且操作的PC也由我掌控,无需兼容所有设备,仅需在该PC上实现强制打印,请问该如何处理?
解决方案
方法1:给域名B配置CORS规则
利用你对域名B服务器的控制权,添加跨域资源共享(CORS)响应头,允许域名A的跨域操作:
- 若使用Nginx服务器,在域名B的配置文件中添加:
(如果域名A是HTTP协议,将add_header Access-Control-Allow-Origin "https://Domain.com"; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS"; add_header Access-Control-Allow-Headers "Content-Type";https替换为http) - 配置完成后重启Nginx,域名A的页面即可正常调用
printWindow.print()。
方法2:用代理HTML页面实现跨域打印指令
如果不想配置CORS,或者PDF直接打开时浏览器默认调用阅读器插件导致无法控制,可以在域名B上创建一个代理HTML页面(比如print-proxy.html):
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>PDF打印代理</title> <style> body, html { margin: 0; padding: 0; height: 100%; } iframe { width: 100%; height: 100%; border: none; } </style> </head> <body> <iframe id="pdfFrame" src="./my.pdf"></iframe> <script> // 监听来自域名A的打印指令 window.addEventListener('message', function(e) { if (e.origin === 'https://Domain.com' && e.data === 'trigger-print') { window.print(); } }); </script> </body> </html>
然后修改域名A的代码,打开这个代理页面并通过postMessage发送打印指令:
var printWindow = window.open('http://8.8.8.8/print-proxy.html', 'Print', 'left=200, top=200, width=950, height=700, toolbar=0, resizable=1'); // 等待页面加载完成后发送指令 setTimeout(function() { printWindow.postMessage('trigger-print', 'http://8.8.8.8'); }, 2000);
方法3:关闭本地浏览器的跨域安全限制(仅自用PC)
因为只需要在自己的PC上实现,可直接关闭浏览器的跨域检查:
- Chrome浏览器:右键点击Chrome快捷方式→属性→在"目标"栏末尾添加
--disable-web-security --user-data-dir="C:/ChromeDevSession"(注意开头有空格),启动后即可解除跨域限制。 - Edge浏览器:操作类似,快捷方式目标栏添加
--disable-web-security --user-data-dir="C:/EdgeDevSession"。
注意:此方法会降低浏览器安全性,仅适合在可控设备上临时使用,不要用于浏览陌生网站。
内容的提问来源于stack exchange,提问作者Carlos Castillo
相关产品推荐
相关产品推荐

