Chrome 阻止了 JavaScript 打印,解决方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10401454/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 09:45:38  来源:igfitidea点击:

JavaScript print blocked by Chrome, Workaround?

javascriptgoogle-chromeprinting

提问by Kamyar Nazeri

I know it has been discussed here before, yet I found no practical solution/workaround for this, I'm hoping if someone has any idea how to resolve this problem!

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

Here's it is:

这是:

If you try to call window.print()method frequently within a single page(as if a user clicks on a print button) in google Chrome, the browser throws a warning message in the console, stating:

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

Ignoring too frequent calls to print()

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

And nothing happens! After several seconds, things go back to normal and print dialog appears the moment you call window.print()command again! To make matters worse, the good Chrome folks use exponential wait time for a page that calls print command, meaning the more user clicks on a button to print, the more he has to wait for the print dialog to appear!

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

This issue has been in chrome for quite some time (14 subsequent versions) and it is confirmedas being an Area-UIbug, I posted it again for google teamyesterday hoping if someone from Chrome team can verify when this incredible annoying feature is going to be fixed!

这个问题在 chrome 中存在了很长一段时间(14 个后续版本),它被确认为一个Area-UI错误,我昨天再次为谷歌团队发布了它,希望 Chrome 团队的人可以验证这个令人难以置信的烦人的功能何时会被修复!

However, what I'm looking for here is a workaround for this problem, is there anythingI can do be able to get this working? My company is developing a highly transactional financial system with lots of reports that needs printing, and for just this one little glitch, the whole project is at risk of running in my favorite google Chrome browser!

但是,我在这里寻找的是解决此问题的方法,有什么我可以做的事情吗?我的公司正在开发一个高度交易的财务系统,其中有很多需要打印的报告,仅此一个小故障,整个项目就有在我最喜欢的谷歌 Chrome 浏览器中运行的风险!

Update:

更新:

Here's the code in Chrome browserthat causes this feature and it looks like that at least 2 seconds is needed before someone calls print command again, so a timer of 2 seconds interval in UI could possibly prevent getting into an infinite wait callback! any other thoughts?

是导致此功能的Chrome 浏览器的代码,看起来在有人再次调用打印命令之前至少需要 2 秒,因此 UI 中间隔为 2 秒的计时器可能会阻止进入无限等待回调!还有其他想法吗?

采纳答案by apsillers

You could conditionally replace the window.print()function:

您可以有条件地替换该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;
            }
        }
    })();
}

Instead of using an external safety timer/wrapper, you can use an internal one. Just add this and window.printbehaves safely in Chrome and normally everywhere else. (Plus, the closure means realPrintFunc, intervaland nextAvailableTimeare private to the new window.print

您可以使用内部的,而不是使用外部安全计时器/包装器。只需添加它,即可window.print在 Chrome 和其他任何地方正常运行。(另外,关闭意味着realPrintFuncinterval并且nextAvailableTime是新的私有的window.print

If you need to coordinate calls to window.printbetween multiple framed pages, you could set nextAvailableTimein the parent page, rather than in the closure, so that all the frames could access a shared value using window.parent.nextAvailableTime.

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

回答by abathur

I've been bumping up against the same issue, and the most direct solution for me was to just create a new window, write what I need to it, close it, and print it. I haven't had to deal with Chrome's limit since I changed it to work this way, and I don't need to do any tracking.

我一直在遇到同样的问题,对我来说最直接的解决方案是创建一个新窗口,写下我需要的内容,关闭它,然后打印它。自从我将其更改为以这种方式工作以来,我就不必处理 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();

回答by Kyle MacFarlane

Everywhere I see mentioning this issue suggests using timers. However they do not solve the issue and I feel like Kamyar is the only person who actually read the source and understands the problem, so I do wonder why he accepted the answer he did.

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

The main problem is that the length of the delay in Chrome is exponential, so for these timers to work their delay has to also be increased on every usage which of course would get very annoying very quickly. Chrome actually only applies the delay after cancelled print requests but we can't detect whether a print is successful or not anyway.

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

Abathur's solution actually works much better than you might expect. I'm not sure if I'll use it but it does work.

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

The good news:

好消息:

1) The delay is actually reduced in more recent versions of Chrome. It now goes: [2, 2, 2, 4, 8, 16, 32, 32, ...].

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

2) Someone took up the issue on August 28th: http://code.google.com/p/chromium/issues/detail?id=50186If you want this issue resolved then please go star it.

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

回答by corbacho

No more work-arounds! Bug fixedas part of v.23 if I'm not wrong.

没有更多的解决方法!错误固定为23节的一部分,如果我没有错。

So if the release cycle is every 6 weeks and Chrome 22 was released 25th of Sep, then by 6th of November(aprox.) the fix will be in the Chrome Stable version

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

回答by AP-Green

My solution would be to call the window.print()less frequently. You could try wrapping window.print()into a method of your own and put a minimum time interval that has to pass before the window.print()is executed again. You can have some kind of change/animation in UI to indicate that work is being done.

我的解决方案是window.print()不那么频繁地打电话。您可以尝试包装window.print()到您自己的方法中,并设置在window.print()再次执行之前必须经过的最小时间间隔。您可以在 UI 中进行某种更改/动画以指示工作正在完成。

"Working"

“在职的”

Unless you think it really think pressing print-button more than once a second/every few seconds helps? I mean if the window.print()operation takes that long it's not your codes fault and there should be a "wait and be patient" -indicator in UI anyway.

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

回答by YMMD

If all your printers are network-compatible, you could change what happens when clicking on the print button. Instead of printing the page, your application could send a request to a server with the URL of the page to print and with an information on which printer to print.

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

The server then launches the print process manually and there will be no browser in between, which could stop you from doing so.

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