如何使用JavaScript对网页进行截图?

153

是否有可能使用JavaScript对网页进行截屏,并将其提交回服务器?

我所关心的不是浏览器安全问题,而是实现方式适用于HTA。但这是否可行?


你能解释一下为什么你想这样做吗?也许有其他替代方案来截屏。 - andyuk
我正在考虑让用户粗略地设计他们想要的东西,包括一些草图和拖放对象。然后,我希望这个“设计”被用作生产过程中某些指令的一部分。这绝对是一个需要用户参与的步骤,没有任何秘密行动 :) - Scott Bennett-McLeish
可能是如何获取访问者的页面截图?的重复问题。 - ilhan
这个回答解决了你的问题吗?使用HTML5/Canvas/JavaScript在浏览器中进行截屏 - Anderson Green
15个回答

144

2
谢谢,你帖子中的链接解释得很清楚。 - Hüseyin BABAL

44

我已经使用一个ActiveX控件为HTA完成了这项操作。在VB6中构建控件以进行屏幕截图非常容易。我不得不使用keybd_event API调用,因为SendKeys无法执行PrintScreen操作。以下是该操作的代码:

Declare Sub keybd_event Lib "user32" _
(ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

Public Const CaptWindow = 2

Public Sub ScreenGrab()
   keybd_event &H12, 0, 0, 0
   keybd_event &H2C, CaptWindow, 0, 0
   keybd_event &H2C, CaptWindow, &H2, 0
   keybd_event &H12, 0, &H2, 0
End Sub

如果你想要将窗口截图复制到剪贴板,那么上述方法只能帮助你完成一半。

另一个选择是,如果你想要截取的窗口是一个HTA,则可以使用XMLHttpRequest将DOM节点发送到服务器,然后在服务器端创建屏幕截图。


我同意Allen的观点,这是一种可能截屏页面的巧妙方法! - Ricket
"HTA" 是什么意思? - Pete Alvin
2
@PeteAlvin HTA是一种超文本应用程序,它是在Internet Explorer中运行特权JS应用程序的一种方式。但现在并不是非常相关。 - Joel Anair

15

我发现的另一种可能的解决方案是http://www.phantomjs.org/,它允许非常容易地对网页进行截图等操作。虽然我最初提出的问题需求已经失效了(工作不同了),但我可能会在未来的项目中集成PhantomJS。


你知道phantomjs是否可以生成页面元素的图像(而不是整个页面)吗? - trusktr
可以的。您可以使用PhantomJS中的此代码片段,或使用CasperJS - zopieux

13

不知道SVG是否有帮助,也许需要查看谷歌的源代码。 - Luke Stanley
1
你可以使用Niklas的html2canvas代码将HTML渲染到画布上,然后将其用于保存图片。 - trusktr

10

如果你在Windows上运行且已安装.NET,可以尝试以下方法:

public Bitmap GenerateScreenshot(string url)
{
    // This method gets a screenshot of the webpage
    // rendered at its full size (height and width)
    return GenerateScreenshot(url, -1, -1);
}

public Bitmap GenerateScreenshot(string url, int width, int height)
{
    // Load the webpage into a WebBrowser control
    WebBrowser wb = new WebBrowser();
    wb.ScrollBarsEnabled = false;
    wb.ScriptErrorsSuppressed = true;
    wb.Navigate(url);
    while (wb.ReadyState != WebBrowserReadyState.Complete) { Application.DoEvents(); }


    // Set the size of the WebBrowser control
    wb.Width = width;
    wb.Height = height;

    if (width == -1)
    {
        // Take Screenshot of the web pages full width
        wb.Width = wb.Document.Body.ScrollRectangle.Width;
    }

    if (height == -1)
    {
        // Take Screenshot of the web pages full height
        wb.Height = wb.Document.Body.ScrollRectangle.Height;
    }

    // Get a Bitmap representation of the webpage as it's rendered in the WebBrowser control
    Bitmap bitmap = new Bitmap(wb.Width, wb.Height);
    wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height));
    wb.Dispose();

    return bitmap;
}

然后你可以通过 PHP 执行以下代码:

exec("CreateScreenShot.exe -url http://.... -save C:/shots domain_page.png");

这样你就能在服务器端得到屏幕截图了。


1
尽管与问题略有不相关,但这是一个很棒的建议!谢谢! - mihai
为什么它无法加载一些样式,即使我可以在IE9中看到它们已经加载了?! - Dr TJ

8

这可能不是您的理想解决方案,但仍值得一提。

Snapsie 是一个开源的 ActiveX 对象,可以捕获并保存 Internet Explorer 的屏幕截图。 客户端注册 DLL 文件后,您应该能够使用 JavaScript 捕获屏幕截图并将文件上传到服务器。缺点:需要在客户端注册 DLL 文件,并且仅适用于 Internet Explorer。


7
我们有一个类似的报告错误的要求。由于这是针对内部网络的情况,我们能够使用浏览器插件(如Firefox的Fireshot和Internet Explorer的IE Screenshot)。

5

2
我非常喜欢 getDisplayMedia,但是 browsershot 的默认用法有些过头了,因为它会拍摄整个窗口的图片,这在大多数情况下可能并不理想。开发者可以控制这一点(将 displaySurface 设置为 applicationbrowsermonitorwindow),用户也可以控制是否允许,但我认为大多数开发者只想要浏览器选项卡的内容,而不是实际的浏览器窗口。 - Dan Atkinson

4

3
我发现dom-to-image做得很好(比html2canvas更好)。参见下面的问题和答案:https://dev59.com/LWgv5IYBdhLWcg3wSewe#32776834 该问题询问如何将其提交回服务器,这应该是可能的,但如果您想下载图像,则需要与FileSaver.js结合使用,并且如果要下载一个包含多个客户端生成的图像文件的zip,请查看jszip

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