通过 JavaScript(或其他方式)截取浏览器的屏幕截图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3316193/
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-08-23 04:07:47  来源:igfitidea点击:

Take Screenshot of Browser via JavaScript (or something else)

javascriptbrowserscreenshot

提问by Thorben Croisé

For support reasons I want to be able for a user to take a screenshot of the current browser window as easy as possible and send it over to the server.

出于支持原因,我希望用户能够尽可能轻松地截取当前浏览器窗口的屏幕截图并将其发送到服务器。

Any (crazy) ideas?

任何(疯狂的)想法?

采纳答案by Gary Rowe

That would appear to be a pretty big security hole in JavaScript if you could do this. Imagine a malicious user installing that code on your site with a XSS attack and then screenshotting all of your daily work. Imagine that happening with your online banking...

如果您可以这样做,这似乎是 JavaScript 中一个相当大的安全漏洞。想象一下,一个恶意用户使用 XSS 攻击在您的站点上安装该代码,然后截取您所有的日常工作。想象一下,您的网上银行会发生这种情况……

However, it is possible to do this sort of thing outside of JavaScript. I developed a Swing application that used screen capture code like thiswhich did a great job of sending an email to the helpdesk with an attached screenshot whenever the user encountered a RuntimeException.

但是,可以在 JavaScript 之外执行此类操作。我开发了一个 Swing 应用程序,它使用这样的屏幕捕获代码,当用户遇到 RuntimeException 时,它可以很好地向服务台发送电子邮件并附上屏幕截图。

I suppose you could experiment with a signed Java applet (shock! horror! noooooo!) that hung around in the corner. If executed with the appropriate security privileges given at installation it might be coerced into executing that kind of screenshot code.

我想您可以试验一个挂在角落里的签名 Java 小程序(震惊!恐怖!noooooo!)。如果在安装时使用适当的安全权限执行,它可能会被强制执行那种屏幕截图代码。

For convenience, here is the code from the site I linked to:

为方便起见,这是我链接到的网站的代码:

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;

...

public void captureScreen(String fileName) throws Exception {

   Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
   Rectangle screenRectangle = new Rectangle(screenSize);
   Robot robot = new Robot();
   BufferedImage image = robot.createScreenCapture(screenRectangle);
   ImageIO.write(image, "png", new File(fileName));
}
...

回答by whoughton

Please see the answer shared here for a relatively successful implementation of this: https://stackoverflow.com/a/6678156/291640

请参阅此处共享的答案,以获得相对成功的实现:https: //stackoverflow.com/a/6678156/291640

Utilizing: https://github.com/niklasvh/html2canvas

利用:https: //github.com/niklasvh/html2canvas

回答by Brian Armstrong

I've seen people either do this with two approaches:

我见过人们用两种方法来做到这一点:

  1. setup a separate server for screenshotting and run a bunch of firefox instances on there, check out these two gem if you're doing it in ruby: selenium-webdriverand headless

  2. use a hosted solution like http://url2png.com(way easier)

  1. 设置一个单独的服务器用于截图并在那里运行一堆 firefox 实例,如果你在 ruby​​ 中做它,请检查这两个 gem:selenium-webdriverheadless

  2. 使用像http://url2png.com这样的托管解决方案(更容易)

回答by MatrixFrog

A webpage can't do this (or at least, I would be very surprised if it could, in any browser) but a Firefox extension can. See https://developer.mozilla.org/en/Drawing_Graphics_with_Canvas#Rendering_Web_Content_Into_A_Canvas-- when that page says "Chrome privileges" that means an extension can do it, but a web page can't.

网页无法做到这一点(或者至少,如果它可以在任何浏览器中执行,我会感到非常惊讶)但 Firefox 扩展程序可以。请参阅https://developer.mozilla.org/en/Drawing_Graphics_with_Canvas#Rendering_Web_Content_Into_A_Canvas- 当该页面显示“Chrome 权限”时,这意味着扩展程序可以执行此操作,但网页不能。

回答by Pete Wilson

Seems to me that support needs (at least) the answers for two questions:

在我看来,支持需要(至少)两个问题的答案:

  1. What does the screen look like? and
  2. Why does it look that way?
  1. 屏幕是什么样子的?和
  2. 为什么看起来是这样?

A screenshot -- a visual -- is very necessary and answers the first question, but it can't answer the second.

屏幕截图——视觉效果——非常必要,可以回答第一个问题,但不能回答第二个问题。

As a first attempt, I'd try to send the entire page up to support. The support tech could display that page in his browser (answers the first question); and could also see the current state of the customer's html (helps to answer the second question).

作为第一次尝试,我会尝试将整个页面发送给支持。支持技术人员可以在他的浏览器中显示该页面(回答第一个问题);并且还可以看到客户的 html 的当前状态(有助于回答第二个问题)。

I'd try to send as much of the page as is available to the client JS by way of AJAX or as the payload of a form. I'd also send info not on the page: anything that affects the state of the page, like cookies or session IDs or whatever.

我会尝试通过 AJAX 或作为表单的有效负载向客户端 JS 发送尽可能多的页面。我还会发送不在页面上的信息:任何影响页面状态的信息,例如 cookie 或会话 ID 或其他任何内容。

The cust might have a submit-like button to start the process.

客户可能有一个类似提交的按钮来启动这个过程。

I think that would work. Let's see: it needs some CGI somewhere on the server that catches the incoming user page and makes it available to support, maybe by writing a disk file. Then the support person can load (or have loaded automatically) that same page. All the other info (cookies and so on) can be put into the page that support sees.

我认为那会奏效。让我们看看:它需要服务器上某处的一些 CGI 来捕获传入的用户页面并使其可用于支持,可能是通过编写磁盘文件。然后支持人员可以加载(或自动加载)同一页面。所有其他信息(cookies 等)都可以放入支持看到的页面。

PLUS: the client JS that handles the submit-button onclick( ) could also include any useful JS variable values!

另外:处理提交按钮 onclick() 的客户端 JS 也可以包含任何有用的 JS 变量值!

Hey, this can work! I'm getting psyched :-)

嘿,这可以工作!我快疯了:-)

HTH

HTH

-- pete

——皮特

回答by Andreas K?berle

You could try to render the whole page in canvas and save this image back to server. have fun :)

您可以尝试在画布中渲染整个页面并将此图像保存回服务器。玩得开心 :)

回答by jamespgilbert

You can also do this with the Fireshot plugin. I use the following code (that I extracted from the API code so I don't need to include the API JS) to make a direct call to the Fireshot object:

您也可以使用 Fireshot 插件执行此操作。我使用以下代码(我从 API 代码中提取,所以我不需要包含 API JS)直接调用 Fireshot 对象:

    var element = document.createElement("FireShotDataElement");
element.setAttribute("Entire", true);
element.setAttribute("Action", 1);
element.setAttribute("Key", "");
element.setAttribute("BASE64Content", "");
element.setAttribute("Data", "C:/Users/jagilber/Downloads/whatev.jpg");

if (typeof(CapturedFrameId) != "undefined")
        element.setAttribute("CapturedFrameId", CapturedFrameId);


document.documentElement.appendChild(element);

var evt = document.createEvent("Events");
evt.initEvent("capturePageEvt", true, false);

element.dispatchEvent(evt);

Note: I don't know if this functionality is only available for the paid version or not.

注意:我不知道这个功能是否只适用于付费版本。

回答by liftarn

Perhaps http://html2canvas.hertzen.com/could be used. Then you can capture the display and then process it.

也许可以使用http://html2canvas.hertzen.com/。然后,您可以捕获显示,然后对其进行处理。

回答by Jens A. Koch

You might try PhantomJs, a headlesss browsing toolkit. http://phantomjs.org/

您可以尝试 PhantomJs,一个无头浏览工具包。 http://phantomjs.org/

The following Javascript example demonstrates basic screenshot functionality:

以下 Javascript 示例演示了基本的屏幕截图功能:

var page = require('webpage').create();

page.settings.userAgent = 'UltimateBrowser/100';
page.viewportSize = { width: 1200, height: 1200 };
page.clipRect = { top: 0, left: 0, width: 1200, height: 1200 };

page.open('https://google.com/', function () {
  page.render('output.png');
  phantom.exit();
});

回答by Seth Jeffery

I understand this post is 5 years old, but for the sake of future visits I'll add my own solution here which I think solves the original post's question without any third-party libraries apart from jQuery.

我知道这篇文章已经有 5 年的历史了,但是为了以后的访问,我将在这里添加我自己的解决方案,我认为除了 jQuery 之外,没有任何第三方库就可以解决原始帖子的问题。

pageClone = $('html').clone();

// Make sure that CSS and images load correctly when opening this clone
pageClone.find('head').append("<base href='" + location.href + "' />");

// OPTIONAL: Remove potentially interfering scripts so the page is totally static
pageClone.find('script').remove();

htmlString = pageClone.html();

You could remove other parts of the DOM you think are unnecessary, such as the support form if it is in a modal window. Or you could choose not to remove scripts if you prefer to maintain some interaction with dynamic controls.

您可以删除您认为不必要的 DOM 的其他部分,例如如果它在模式窗口中的支持表单。或者,如果您希望与动态控件保持某种交互,您可以选择不删除脚本。

Send that string to the server, either in a hidden field or by AJAX, and then on the server side just attach the whole lot as an HTML file to the support email.

将该字符串发送到服务器,无论是在隐藏字段中还是通过 AJAX,然后在服务器端,只需将整个批次作为 HTML 文件附加到支持电子邮件中。

The benefits of this are that you'll get not just a screenshot but the entire scrollable page in its current form, plus you can even inspect and debug the DOM.

这样做的好处是,您不仅可以获得屏幕截图,还可以获得当前形式的整个可滚动页面,而且您甚至可以检查和调试 DOM。