3

Backstory

I wrote a specialized image inliner script that is intended to be used with both GreaseMonkey and Google Chrome. It is supposed to download PNG files and store them in data: urls in image src attributes. This may sound ridiculous, but a certain website sets Content-Disposition to attachment for images, and I don't want the «Save As» dialog to pop up every time.

The actual question

The script fetches data with an XMLHttpRequest, encodes it into base64 and stores it in a proper place. So far, good. But it only works when I run it through both Firebug and Chrome dev consoles, and does not when I use it as a proper userscript. As far as I understand, this is because Greasemonkey scripts cannot use XMLHttpRequest objects directly and should rely on calls to GM_xmlhttpRequest instead. However, I cannot set responseType to "blob" or "arraybuffer" that way, and the binary parameter seems to only work for sending data through POST requests. I only get Unicode strings.

Just in case, the images are served from the same domain as the page that links to them. I believe it satisfies the «same origin» thingy.

http://wiki.greasespot.net/GM_xmlhttpRequest here are the GM_xmlhttpRequest docs.

Is there a way to fetch an arraybuffer from within a Greasemonkey userscript?

Mischa Arefiev
  • 5,227
  • 4
  • 26
  • 34
  • possible duplicate of [Downloading an image using XMLHttpRequest in a userscript](http://stackoverflow.com/questions/8778863/downloading-an-image-using-xmlhttprequest-in-a-userscript) – Brock Adams May 29 '12 at 01:27

2 Answers2

2

If it is same-domain, then you can use XMLHttpRequest, with no problems. The only reason to use GM_xmlhttpRequest (which currently has a crippled subset of functionality) is if the images/files are cross domain.

For same-domain, you can use XHR2 as shown in this answer.

For cross-domain, you must: use GM_xmlhttpRequest, override the mime-type, and use a custom encoder algorithm. Again, this is all shown in that same answer.


However, it sounds like you are just trying to make it easier to download images? If that is so, then you might be better off just using the excellent DownThemAll extension.

Community
  • 1
  • 1
Brock Adams
  • 90,639
  • 22
  • 233
  • 295
  • Thanks! Chrome does not allow setting `responseType` for synchronous requests (`open(,,false)`) though, and asynchronous requests don't work for some reason (it never calls `onload`), but it works in Greasemonkey. – Mischa Arefiev May 29 '12 at 09:20
  • I am trying to inline images into the page on a certain website, so using an extension just for the one site is not an option for me. – Mischa Arefiev May 29 '12 at 09:21
1

overrideMimeType String (Compatibility: 0.6.8+) Optional. A MIME type to specify with the request (E.G. "text/html; charset=ISO-8859-1").

You can set this to plain/text; charset=x-user-defined (the type doesn't matter but the charset does), bitwise AND through the response string and add the values to a typed array and get the buffer:

var text = xhr.responseText,
    len = text.length,
    arr = new Uint8Array(len),
    i = 0;

    for( i = 0; i < len; ++i ) {
        arr[i] = text.charCodeAt(i) & 0xFF;
    }

    arr.buffer //The arraybuffer

Note: this is for raw binary responses, not base64.

Esailija
  • 138,174
  • 23
  • 272
  • 326