How to load someone elseโ€™s image through a POST request in a browser?

My web application (HTML5 + JavaScript) should display PNG images created using an external web service.

However, this web service only supports POST requests . (More precisely, it provides GET requests, but I have to pass in large arguments that make the GET URL too long.)

In addition, the web service has a different domain than the web application and does not provide the corresponding CORS headers, so Ajax (XMLHTTPRequest) does not work.

Is it possible for my web application to download and display an external image through a POST request?

I am asking for a solution that is different from the following unpleasant workarounds that are already well known to me:

  • without setting up a local proxy server that translates the request (and also bypasses a policy of the same origin)
  • without using a remote proxy server of any unknown user
  • without using flash
  • without using java applets
  • without using OS features such as ActiveX controls

However, a solution that does not work with Internet Explorer is acceptable. Even a special solution for Firefox or Chrome is welcome.

+5
source share
3 answers

Horrible hack:

Submit the form in an iframe and get the image displayed in the iframe.

(But don't do this, it looks like the web server is designed to avoid inline images directly on other sites.)

+6
source

I have some possible solutions ...

Solution 1

If your image is less than 25kb, you can do the following via YQL: select * from data.uri where url="http://jquery.com/jquery-wp-content/themes/jquery/images/ logo-jquery@2x.png " As a result, you can just capture the base64 image and go on. To do a POST through YQL, you should add something like and postdata="foo=foo&bar=bar" to check this article .

Caution: the performance of this method is probably low. There is quite a bit of latency, which makes the jump from the end user to YQL to the service, and then comes back. There is also some server side processing. YQL makes base64 encode the image and deliver some JSON response.

Decision 2

Enable CORS or go through another proxy. Once you do this, if you still cannot get the base64 data, you need to do 2 things. First add a jQuery transport that processes the binary. The second process executes a binary blob and converts it to base64.

Here is jQuery Binary Transport I found

 $.ajaxTransport("+binary", function(options, originalOptions, jqXHR){ // check for conditions and support for blob / arraybuffer response type if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob))))) { return { // create new XMLHttpRequest send: function(headers, callback){ // setup all variables var xhr = new XMLHttpRequest(), url = options.url, type = options.type, async = options.async || true, // blob or arraybuffer. Default is blob dataType = options.responseType || "blob", data = options.data || null, username = options.username || null, password = options.password || null; xhr.addEventListener('load', function(){ var data = {}; data[options.dataType] = xhr.response; // make callback and send data callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders()); }); xhr.open(type, url, async, username, password); // setup custom headers for (var i in headers ) { xhr.setRequestHeader(i, headers[i] ); } xhr.responseType = dataType; xhr.send(data); }, abort: function(){ jqXHR.abort(); } }; } }); 

After adding the transport, you can make any AJAX request.

 $.ajax({ type: "POST", url: 'http://myservice.com/service/v1/somethingsomething', dataType: 'binary', success: function(imgData) { var img = new Image(), reader = new window.FileReader(); reader.readAsDataURL(imgData); reader.onloadend = function() { img.src = reader.result $('#logo-events').append(img); } } }); 

The reader should take Blob and release the base64 version. When the reader finishes the conversion / reading, he will create both the image and add it somewhere. GET or POST no longer matters.

0
source

I found this related question: Post data to JsonP

And I think this may be applicable in your case.

Basically, run your jsonp request on your server (a policy with the same source should not be a problem) and download the <img> response

Like @Quentin's answer, this hack uses a (hidden) iframe

0
source

All Articles