【问题标题】:JavaScript print blocked by Chrome, Workaround?Chrome 阻止了 JavaScript 打印,解决方法?
【发布时间】:2012-05-11 04:50:23
【问题描述】:

我知道以前在这里讨论过,但我没有找到实用的解决方案/解决方法,我希望有人知道如何解决这个问题!

这里是:

如果您尝试在谷歌浏览器的单个页面中频繁调用window.print() 方法(就像用户单击打印按钮一样),浏览器会在控制台中抛出警告消息,说明:

忽略对 print() 的过于频繁的调用

什么也没发生!几秒钟后,一切恢复正常,并在您再次调用window.print() 命令时出现打印对话框!更糟糕的是,优秀的 Chrome 人员对调用打印命令的页面使用指数等待时间,这意味着用户点击按钮打印的次数越多,他等待打印对话框出现的时间就越长!

这个问题在 chrome 中已经存在了很长一段时间(14 个后续版本),已确认Area-UI 错误,我昨天 posted it again for google team 希望 Chrome 团队的人可以验证什么时候修复这个令人难以置信的烦人功能!

但是,我在这里寻找的是解决此问题的方法,是否有 任何事情我可以做到这一点?我的公司正在开发一个高度交易性的财务系统,其中包含大量需要打印的报告,而仅仅因为这个小故障,整个项目就有可能在我最喜欢的谷歌 Chrome 浏览器中运行!

更新:

Here's the code in Chrome browser 导致此功能,看起来至少需要 2 秒才能有人再次调用打印命令,因此 UI 中 2 秒间隔的计时器可能会阻止进入无限等待回调!还有其他想法吗?

【问题讨论】:

  • 我能想到的唯一解决方法是有一个内部计时器(跟踪何时可以调用打印),并且当按下打印按钮时有一个类似于 AJAX 的动画,直到打印真的叫。这不是很好,因为它仍然会延迟打印过程,但它看起来比弹出错误要好。
  • @gillesc:是的,这比单击按钮时“什么都没有”要好,然后您一次又一次地单击使情况变得更糟!我在 Chrome 浏览器中找到了导致此功能的代码行:git.chromium.org/gitweb/… 并且看起来至少需要 2 秒才能有人再次调用打印命令,因此 2 秒间隔的计时器可能会阻止进入无限等待回调!
  • window.print的调用是在同一页面还是不同页面?如果不同,它们是在新窗口/标签还是 iframe 中?还是同一个标签,通过重定向?
  • window.print 命令位于页面内的 iframe 上,我正在构建一个报表查看器组件,其中包含处理报表所需的所有方法,例如:nextpreviousfindexportprint 按钮。后者导致谷歌浏览器出现问题
  • 希望问题得到解决,但下划线的去抖动听起来像是一个可行的解决方法。 documentcloud.github.com/underscore/#debounce

标签: javascript google-chrome printing


【解决方案1】:

您可以有条件地替换 window.print() 函数:

// detect if browser is Chrome
if(navigator.userAgent.toLowerCase().indexOf("chrome") >  -1) {
    // wrap private vars in a closure
    (function() {
        var realPrintFunc = window.print;
        var interval = 2500; // 2.5 secs
        var nextAvailableTime = +new Date(); // when we can safely print again

        // overwrite window.print function
        window.print = function() {
            var now = +new Date();
            // if the next available time is in the past, print now
            if(now > nextAvailableTime) {
                realPrintFunc();
                nextAvailableTime = now + interval;
            } else {
                // print when next available
                setTimeout(realPrintFunc, nextAvailableTime - now);
                nextAvailableTime += interval;
            }
        }
    })();
}

您可以使用内部安全计时器/包装器,而不是使用外部安全计时器/包装器。只需添加这个,window.print 在 Chrome 和其他任何地方都可以安全运行。 (另外,关闭意味着 realPrintFuncintervalnextAvailableTime 对新的 window.print 是私有的

如果您需要在多个框架页面之间协调对window.print 的调用,您可以在父页面中而不是在闭包中设置nextAvailableTime,以便所有框架都可以使用window.parent.nextAvailableTime 访问共享值。

【讨论】:

  • 这个sn-p确实有效,但是你需要考虑到频繁调用打印只有当有人取消打印对话框时才会被阻塞,所以只有当对话框消失时才需要启动计时器,我想这可以通过存储setTimeout 的引用并在创建新引用时清除它来很好地完成,或者您可以在setTimeout 启动时设置繁忙标志并且在设置标志时不要启动新标志。感谢您的宝贵时间
  • 这个 sn-p 对某些人仍然有效吗?我发现我仍然看到ignoring too frequent calls to print 错误,同时使用逐字给出的代码,以及一些监视标志/超时的变体,因此不设置进一步的超时函数。使用 Chrome 22.0.1229.94。
【解决方案2】:

我遇到了同样的问题,对我来说最直接的解决方案就是创建一个新窗口,写下我需要的内容,关闭它,然后打印它。我不必处理 Chrome 的限制,因为我将其更改为以这种方式工作,并且我不需要进行任何跟踪。

print_window= window.open();
print_window.document.write(print_css + divToPrint[0].outerHTML+"</html>");
print_window.document.close();
print_window.focus();
print_window.print();
print_window.close();

【讨论】:

    【解决方案3】:

    我的解决方案是减少拨打window.print() 的频率。您可以尝试将window.print() 包装到您自己的方法中,并设置在再次执行window.print() 之前必须经过的最小时间间隔。您可以在 UI 中进行某种更改/动画,以表明工作正在完成。

    “工作”

    除非您认为它真的认为每秒/每隔几秒按一次以上打印按钮会有所帮助?我的意思是,如果window.print() 操作花费了那么长时间,那不是您的代码错误,无论如何,UI 中应该有一个“等待并耐心等待”的指示符。

    【讨论】:

    • 是的,这就是我目前所做的,2 秒的间隔是发送另一个打印命令之前的最短等待时间
    【解决方案4】:

    如果您的所有打印机都与网络兼容,您可以更改单击打印按钮时发生的情况。除了打印页面,您的应用程序可以向服务器发送一个请求,其中包含要打印的页面的 URL 以及要打印的打印机的信息。

    然后服务器手动启动打印过程,中间不会有浏览器,这可能会阻止您这样做。

    【讨论】:

    • 很好的解决方案,我会在程序安装在局域网中时这样做,但不幸的是,该软件同时针对局域网和广域网!
    【解决方案5】:

    我看到提到这个问题的所有地方都建议使用计时器。但是他们并没有解决问题,我觉得 Kamyar 是唯一真正阅读源代码并理解问题的人,所以我想知道他为什么接受他所做的答案。

    主要问题是 Chrome 中的延迟时间是指数级的,因此为了让这些计时器工作,它们的延迟也必须在每次使用时增加,这当然会很快变得非常烦人。 Chrome 实际上只在取消打印请求后应用延迟,但我们无法检测打印是否成功。

    Abathur 的解决方案实际上比您预期的要好得多。我不确定我是否会使用它,但它确实有效。

    好消息:

    1) 在较新版本的 Chrome 中,延迟实际上有所减少。现在是:[2, 2, 2, 4, 8, 16, 32, 32, ...]

    2) 8 月 28 日有人处理了这个问题:http://code.google.com/p/chromium/issues/detail?id=50186 如果你想解决这个问题,请给它加星。

    【讨论】:

      【解决方案6】:

      没有更多的变通办法! 如果我没记错的话,错误 fixed 作为 v.23 的一部分。

      因此,如果发布周期是每 6 周一次,并且 Chrome 22 于 9 月 25 日发布,那么 11 月 6 日(大约)修复将在 Chrome 稳定版中

      【讨论】:

      • 我有 23 个,但仍然是个问题。
      猜你喜欢
      • 2011-07-14
      • 2016-12-08
      • 1970-01-01
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多