10

I want to perform a javascript xhr request for a png file from a C# webserver which I wrote. Here is the code I use

    var imgUrl = "http://localhost:8085/AnImage.png?" + now;
    var request = new XMLHttpRequest();
    request.open('GET', imgUrl, false);
    request.send(); // this is in a try/catch

On the server-side I send back the file and add a Content-Disposition header. I obtain the following response

The headers obtained in the response, with Firebug

I made sure that Content-Disposition was attached in the headers after the Content-Type (the screenshot is from Firebug, which appends in alphabetical order).

The results is that no dialog box is triggered, am I missing something in the response?

edit: I want to perform everything in javascript for several reasons. First: I don't want to show the image and I want to keep everything behind the curtain. Second: when requesting the image I want the Content-Disposition to be added only on particular requests. Such requests are marked with a "Warning" header with value "AttachmentRequest"

request.setRequestHeader("Warning","AttachmentRequest");
malber
  • 1,053
  • 4
  • 16
  • 24
  • why would you need to do that ? you can just load the image with a Image object , no need for Ajax. – mpm Dec 18 '12 at 09:30
  • @camus Totally different. Using the `content-disposition` like this should "force" the user to download the file, not just have the browser "download" it for itself – Ian Dec 18 '12 at 09:32
  • @Ian using ajax will not force anything either. – mpm Dec 18 '12 at 09:36
  • 1
    @camus That's the point of the question. How to get it to force the download. But either way, AJAX isn't necessary, unless there's some kind of form POST that they need to like generate an image or something (doesn't look like that here) – Ian Dec 18 '12 at 09:38
  • My point still stands , you cant use ajax for that. – mpm Dec 18 '12 at 09:42
  • @mpm how can you deduce that there is no dynamic image generation going on here? – FlavorScape Apr 16 '13 at 18:25

1 Answers1

11

I don't think Content-Disposition triggers any file save dialog when the request is via XHR. The use of XHR suggests you're going to handle the result in code.

If you want the user to be prompted to save the image to a file, I've used this technique successfully:

window.open("http://localhost:8085/AnImage.png?" + now);

It has the downside that it flashes a blank open window briefly until the header arrives, then the new window closes and the "save file" dialog box appears.

Using an iframe may prevent the window flashing:

var f = document.createElement('iframe');
f.style.position = "absolute";
f.style.left = "-10000px";
f.src = "http://localhost:8085/AnImage.png?" + now;
document.body.appendChild(f);

Separately, I wonder what effect (if any) Content-Disposition has on the handling of an img element:

var img = document.createElement('img');
img.style.position = "absolute";
img.style.left = "-10000px";
img.src = "http://localhost:8085/AnImage.png?" + now;
document.body.appendChild(img);

I haven't tried that, but the browser might respect the header. You'd need to be sure to test on all of the browsers you want to support.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    I think the way it's normally done without the `window.open`/flashing is with an iframe...but still using `content-disposition` – Ian Dec 18 '12 at 09:39
  • The appendChild workaround doesn't work but the window.open trick works nicely on the browsers we want to use (FF, Chrome and *cough cough* IE). Many thanks TJ – malber Dec 18 '12 at 09:49
  • @Ian: Good point, yes (and embarrassingly, [that's what I usually do](http://stackoverflow.com/a/2064957/157247) although in my case there's almost always a POST involved and so it's more complicated). Thanks, I've updated the answer. – T.J. Crowder Dec 18 '12 at 09:51
  • @malber: Glad that helped! You might also try an `iframe` (I've updated the answer, and in the comments above I've linked another answer of mine here on SO that describes a technique for showing a "one moment" div or similar until the download starts...). – T.J. Crowder Dec 18 '12 at 09:52
  • TJ the iframe trick works perfectly, thanks! Could you please replace the document.body.appendChild(img); to document.body.appendChild(f); in the first code snippet please? – malber Dec 18 '12 at 09:57
  • IS it possible to get content-disposition from header. I have the same problem. Its getting null when i try to read from headerxhr.getResponseHeader('Content-Disposition'); – Arun M R Nair May 05 '15 at 10:46