26

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?

Thorben Croisé
  • 12,407
  • 8
  • 39
  • 50
  • 1
    You could possibly capture the viewport in which the page resides, but I really doubt you could capture the whole window. That would be a security risk wouldn't it. – Benbob Jul 23 '10 at 07:43
  • 2
    There are drop in solutions for this in 2013. [Usersnap](http://www.usersnap.com) can be installed as easy as Google analytics and you will get accurate screenshots from your visitors (they don't have to install anything. No Java, no Flash, no ActiveX, no whatsoever). – Gregor Jun 19 '13 at 15:58
  • Possible duplicate of [Using HTML5/Canvas/JavaScript to take screenshots](http://stackoverflow.com/questions/4912092/using-html5-canvas-javascript-to-take-screenshots) – Zach Saucier Sep 10 '16 at 15:42

15 Answers15

8

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...

However, it is possible to do this sort of thing outside of JavaScript. I developed a Swing application that used screen capture code like this which did a great job of sending an email to the helpdesk with an attached screenshot whenever the user encountered a 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.

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));
}
...
Gary
  • 7,167
  • 3
  • 38
  • 57
  • 7
    That security point doesn't make a whole lot of sense since you can just monitor all the keypresses and their targets in JavaScript. – Gregor Weber Oct 13 '13 at 21:16
  • Think about entering a password using a series of dropdowns. Monitoring a keyboard won't help, but a series of screenshots will. – Gary Oct 14 '13 at 13:02
  • Then you could monitor form changes. Unless we are talking flash, there isn't really much that couldn't be monitored by JS. – Gregor Weber Oct 14 '13 at 18:50
  • If you can inject arbitary JS in the client browser - and you are a bit skilled - you can do almost everything. That argument justifies nothing about this being crazy or not.. – Áxel Costas Pena Nov 25 '13 at 14:50
  • 3
    I don't understand this whole arguing against security concerns. Gary's point is totally valid. Imagine this: If a random website includes your Facebook, Dropbox or a website with even more sensitive data via an iframe (which you will automatically see as yourself because of your coookies), and that website can then take a screenshot of that and send it somewhere (possibly for automatic image processing) - How would you feel about that? – Domi Dec 29 '14 at 06:59
  • 3
    JavaScript can grab the entire HTML dom and CSS of the page. That's as good as (if not better than) a screenshot. You can then render the page in PhantomJS similar to Jens A. Koch's answer, or just save it as an HTML file and open it in a browser. – Seth Jeffery Apr 13 '15 at 09:36
5

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

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

Community
  • 1
  • 1
whoughton
  • 1,395
  • 11
  • 21
3

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

Andreas Köberle
  • 106,652
  • 57
  • 273
  • 297
  • This can be done, but not directly from the web page. You can do it from a Firefox extension (and, presumably an extension in various other browsers as well, though I don't know). See my answer. – Tyler Jul 23 '10 at 08:25
3

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.

Tyler
  • 21,762
  • 11
  • 61
  • 90
3

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?

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).

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.

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.

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

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

HTH

-- pete

Pete Wilson
  • 8,610
  • 6
  • 39
  • 51
3

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-webdriver and headless

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

Brian Armstrong
  • 19,707
  • 17
  • 115
  • 144
2

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:

    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.

2

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

liftarn
  • 429
  • 3
  • 21
2

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

The following Javascript example demonstrates basic screenshot functionality:

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();
});
Jens A. Koch
  • 39,862
  • 13
  • 113
  • 141
2

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.

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.

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.

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.

Seth Jeffery
  • 1,110
  • 1
  • 8
  • 8
  • I hope this works for complex Javascript base SPAs (single page applications)! – Kieveli Sep 19 '16 at 12:57
  • The script tags are removed so you just end up with static HTML of whatever you currently see, but you wouldn't be able to interact with it. You probably wouldn't want to keep the script tags in a SPA because they'd probably reset or re-render the page. – Seth Jeffery Sep 28 '16 at 09:36
1

Print Screen? Old school and a couple of keypresses, but it works!

Toby
  • 8,483
  • 13
  • 45
  • 68
1

This may not work for you, but on IE you can use the snapsie plugin. It doesn't seem to be in development anymore, but the last release is available from the linked site.

ars
  • 120,335
  • 23
  • 147
  • 134
1

i thing you need a activeX controls. without it i can't imagine. you can force user to install them first after the installation on client side activex controls should work and you can capture.

1

We are temporarily collecting Ajax states, data in form fields and session information. Then we re-render it at the support desk. Since we test and integrate for all browsers, there are hardly any support cases for display reasons.

Have a look at the red button at the bottom on holidaycheck

Alternatively there is html2canvas of Google. But it is only applicable for never browsers and I've never tried it.

schmijos
  • 8,114
  • 3
  • 50
  • 58
0

In JavaScript? No. I do work for a security company (sort of NetNanny type stuff) and the only effective way we've found to do screen captures of the user is with a hidden application.

AcidRaZor
  • 566
  • 4
  • 9