如何在JavaScript客户端截取网站屏幕截图 / 谷歌是如何实现这一功能的?(无需访问硬盘)

245
我正在开发一个web应用程序,需要在客户端(浏览器)端呈现页面并截取屏幕截图。我不需要将屏幕截图保存在本地硬盘上,只需将其保存在RAM中,并稍后将其发送到应用程序服务器。
我研究了以下内容:
  1. 类似BrowserShots的服务...
  2. 机械化浏览器...
  3. wkhtmltoimage...
  4. Python WebKit2PNG...
但以上方法都不能满足我的需求,我需要的是:
  1. 在浏览器端处理(生成页面的屏幕截图)。不需要保存在硬盘上!只需...
  2. 将图像发送到服务器进行进一步处理。
  3. 捕获整个页面(而不仅仅是可见部分)
最后,我发现了Google的反馈工具(在YouTube页脚单击“反馈”即可看到此工具)。它包含用于JPG编码的JavaScript和其他两个巨大的脚本,我无法确定它们确切的作用...
但是它是在客户端上处理的-否则就没有必要将这个巨大的JPEG编码器放到代码中了!
有人知道他们是如何完成它/我该如何完成吗?
以下是反馈(在某些屏幕上报告错误)的示例:

Feedback/report bug example


3
这个SO问答可能会有帮助 https://dev59.com/cXVD5IYBdhLWcg3wL4cA - Jim Blackler
@ZachSaucier 谢谢,但正如另一个答案所述:“可能不是真实表示的100%准确,因为它没有进行实际截图”。 - Paweł Szymański
@Michał Perłakowski 这个问题比标记为重复的那个更深入和解决方案更多。如果有一个应该被标记为重复,那么应该是另一个。 - Paweł Szymański
另请参见https://dev59.com/LWgv5IYBdhLWcg3wSewe#32776834。 - maltem-za
“Proper”截屏将绕过XSS保护,因为您将能够查看您无权访问的不同域的iframes。由于这个原因,我认为这是不可能的,也不会被实现。例如,使用Facebook社交小部件并截取页面的屏幕截图,您将能够看到任何已登录Facebook的访客的姓名。 - Rolf
2个回答

88

7
谢谢,但是引用的话:“可能不是100%准确的真实表现,因为它没有制作实际的截图。”这对我来说不太行 :(。 - Paweł Szymański
如果您需要这样的功能,我相信Flash适合您。http://www.coldfusion.se/devnet/air/flex/articles/air_screenrecording.html但是,我怀疑它是否可以在网页上轻松实现,因为这样的屏幕截图可能会被用于恶意行为和侵犯隐私。 - Vaibhav Garg
2
@Pawel Szymański Google反馈也不是100%准确的。尝试添加一些列表项(带有默认图标),在不同浏览器上尝试文本下划线(例如FF与Chrome相比)并使用高字体大小(以获得更好的可见性),或者只是一堆不同的更罕见的CSS3属性。您会发现它远非100%,除非您想使用纯JavaScript本地化,否则目前这是唯一的选择。 - Niklas
4
对于来晚的人...现在可以用 navigator.mediaDevices.getDisplayMedia({video: true}) 然后 const stream = await startCapture(); const track = stream.getVideoTracks()[0]; let imageCapture = new ImageCapture(track); 最后 imageCapture.grabFrame() 来完成此操作并返回一个包含图像位图的 promise。 - jscul

16

我需要在自己编写的Web应用程序中对受JWT保护且大量使用Angular的页面上的div进行快照。

我尝试了上述任何方法都没有成功。

最终,我采取了所需div的outerHTML,稍微清理了一下 (*) ,然后将其发送到服务器,对其运行wkhtmltopdf以生成pdf文件。

这对我来说工作得非常好。

(*) 我网页中的各种输入设备在查看pdf时未呈现为已选或其文本值... 因此,在将其发送到渲染之前,我在html上运行了一些jQuery。例如:对于文本输入项,我将它们的.val()复制到'value'属性中,wkhtmlpdf就可以看到它们。


您可以使用类似的技术,利用GrabzIt免费的HTML到图像JavaScript API,只需确保网页HTML中所有资源,如CSS、Javascript和图像文件等都需要使用绝对URL,然后使用JavaScript获取外部HTML并将其传递给GrabzIt的API即可。 - PHP Rocks

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