谷歌浏览器在打开子窗口的打印预览时会阻止Ajax请求。

19

有2个文件:index.htmlprint.html

第一个文件包含一个按钮,使用简单命令打开print.html

window.open("print.html", "_blank", "menubar=yes,toolbar=yes,status,scrollbars,resizable");

print.html 只包含一个按钮,点击它可以打开打印预览对话框:

<button onclick="window.print();">

当打开打印预览对话框时会出现问题。在这种情况下,对于 index.html 上的任何操作 - 即发起 ajax 请求的其他文件 - 都将被临时阻塞并放入队列中。只有当预览关闭时,浏览器才会触发所有请求。

我只在 Google Chrome (24.0.1312.52 m) 中看到这个问题。

有人可以确认这是 Chrome 的 bug 吗?


1
请纠正我,但在我看来这似乎不是一个错误。打印预览不是模式对话框吗?为什么它打开时应该触发Ajax请求? - Pekka
2
index.html和print.html是两个不同的窗口。index使用window.open打开了print.html。打印预览在print.html上打开。为什么index.html被阻止了?阻止打印窗口是可以的。 - John Smith
Ajax请求是在索引上启动的,以更清晰明了。 - John Smith
2
我确认在Windows 8上Chrome 34上的情况,我已经尝试过Canary版本v26,它可以正常工作。更糟糕的是,如果用户实际上使用窗口的关闭按钮(而不是打印对话框中的取消按钮),它会将打印对话框保持在后台或其他某个地方,并防止任何后续的XHR请求。 - jValdron
我也可以确认这个问题 - 在Windows 7上,使用最新版本的Chrome(34.0.1847.131 m),通过'X'符号关闭打印窗口不会继续执行XHR请求。 - stuXnet
显示剩余2条评论
4个回答

2

Chrome浏览器存在一个bug,当DOM中有一个<iframe>标签时,window.print()函数无法正常工作。可以通过调用以下函数来解决这个问题:

function printPage() {
    window.print();

    //workaround for Chrome bug - https://code.google.com/p/chromium/issues/detail?id=141633
    if (window.stop) {
        location.reload(); //triggering unload (e.g. reloading the page) makes the print dialog appear
        window.stop(); //immediately stop reloading
    }
    return false;
}

我遇到了类似的问题,这是在Chrome版本37.0.2062.103 m上发生的。你的解决方案只起作用一次。使用相同的页面实例重试后,打印对话框没有从window.open打开的页面中打开。我提升了它的优先级,因为这是一个不错的尝试,也许可以让它正常工作。 - Josef.B
对于那些感兴趣的人,这里是已提交的bug...它说这个问题在Chrome的v34和v35版本中已经被修复,但自那以后又重新出现。 - incutonez
我也遇到了同样的问题,但是在两个不同的标签页中(请参见http://stackoverflow.com/questions/42932835/angular-js-print-tab-blocks-http-request-google-chrome)。我该如何在我的情况下使用这个解决方法? - molerat

1

您的服务器没有添加ORIGIN标头。您需要在.htaccess文件中添加它。例如:

Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

或者您可以在print.html中使用PHP添加它(如果您能在html文件中使用PHP)。

header ("Access-Control-Allow-Origin: *");
header ("Access-Control-Allow-Headers: origin, x-requested-with, content-type");
header ("Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS");

1

您需要在Apache上安装mod_headers并将其设置在.htaccess上。

Header add Access-Control-Allow-Origin "*"

0

我在使用Chrome时遇到了类似的问题 - 由于安全策略,它无法访问本地文件。 当我进行AJAX调用时,会出现以下错误

XMLHttpRequest cannot load file:///*. Origin null is not allowed by Access-Control-Allow-Origin.

据我所知,您应该使用参数启动Chrome:
--allow-file-access-from-files

希望有所帮助。

和John遇到了同样的问题,我很抱歉地说--allow-file-access-from-files并不能解决它 :/ - stuXnet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接