1

I am building an extension in CrossRider. I need to save images/icons, which I have their url, in a database. They are tiny images and won't be a problem in the database. I might have something like that accessible to background.js:

<img src="http://something.com/icon.ico" alt="icon">

And I want to be able to serialize that image to the database (it's a key/value database) and deserialize that later and display it. Something like HTML5's FileReader.readAsDataUrl() will be good, but I can't use that method because it seems too tied to forms.

Thanks ([-|).

MadeOfAir
  • 2,933
  • 5
  • 31
  • 39

2 Answers2

2

Base64 conversion to display the image doesn't seem to be necessary:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://g.etfv.co/http://www.google.com', true);
xhr.responseType = 'blob';
xhr.onload = function (e) {
    var icon_blob = xhr.response; //That can be saved to db
    var fr = new FileReader();
    fr.onload = function(e) {
        document.getElementById('myicon').src = fr.result; //Display saved icon
    };
    fr.readAsDataURL(icon_blob);
};
xhr.send(null);

Here's it on JSFiddle.

MadeOfAir
  • 2,933
  • 5
  • 31
  • 39
1

One solution might be to draw the image on a canvas and then use .toDataURL(). See How to get image bytes string (base64) in html5, jquery, javascript? for an example.

You can also fetch binary data via AJAX. Newer browsers can use XMLHttpRequest to retrieve an ArrayBuffer (essentially a byte array). See MDN: Sending and Receiving Binary Data for more information on that. As mentioned in that article, binary data can also be received by setting .overrideMimeType('text\/plain; charset=x-user-defined') on the AJAX request. The latter technique works in older browsers and with jQuery's AJAX functions. However, any type of AJAX will require you to get around the same-origin policy (e.g., by creating a backend web service that fetches/proxies the images and adds the HTTP header Access-Control-Allow-Origin: *).

Binary AJAX example: http://jsfiddle.net/te7L4/

Community
  • 1
  • 1
quietmint
  • 13,885
  • 6
  • 48
  • 73
  • Well, I considered both options, but none seem to fit because the image resides on a different domain. The first solution fails with security warnings and the second won't work because of the `same origin policy`. Any more ideas please? – MadeOfAir Dec 21 '13 at 00:13
  • @MadeOfAir Can you build a backend service to fetch/proxy the icons? If you send the HTTP header `Access-Control-Allow-Origin: *` with the response you can get around the same origin policy ([Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS)). If these are favicons, there's an existing service at http://g.etfv.co/ which does exactly this. – quietmint Dec 21 '13 at 01:07
  • Ok, I am getting closer. But I don't know what kind of data I am getting with a request like that `$.get("http://g.etfv.co/http://www.google.com", function(data)...);`. I have tried several conversions, assuming the data is binary, converted it to hex string then used `hexToBase64()` specified [here](http://stackoverflow.com/a/14918390/1433559), prepended "data:image/x-icon;base64,", but that didn't work. – MadeOfAir Dec 21 '13 at 18:50
  • @MadeOfAir jQuery's AJAX functions can't give you an `ArrayBuffer`. You either need to use the native `XMLHttpRequest`, or you can use the charset hack mentioned in the article. I've posted an example showing each technique. – quietmint Dec 21 '13 at 19:46
  • I think I didn't clarify myself. I need to display that icon as well as save it to database. I've edited the question above. Anyway, the method you posted allows me to retrieve the icon as bytes, and I need that in base64 string so I can set it as `img.src`, right?. Then maybe `blob` data type is more suitable than a `bytearray`. – MadeOfAir Dec 21 '13 at 21:16