views:

4991

answers:

4

Is there a way to force a save as dialog box for www.example.com/example.pdf in ff? (i can't change the headers)

+2  A: 

The only other way I can think of is modify Firefox settings. I assume you can't do this.

EDIT:

I cobbled together a client-side solution based on the data URI idea. It uses a modified version of a base64 encoder and a technique for binary XMLHTTPrequests The script downloads the PDF file, then generates and places a data URI link dynamically using the base64 encoder.

It should be useful when you want octet stream encoding but don't have access to the server (as seems to be the case for the OP).

Note, I just posted an example using hunts.pdf, which the OP was testing with.

/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/

var Base64 = {

    // private property
    _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

    // public method for encoding
    encode : function (input) {
     var output = "";
     var chr1, chr2, chr2raw, chr3, chr3raw, enc1, enc2, enc3, enc4;
     var i = 0;

     //input = Base64._utf8_encode(input);

     while (i < input.length) {

      chr1 = input.charCodeAt(i++) & 0xFF;
      chr2 = isNaN(chr2raw = input.charCodeAt(i++)) ? NaN : (chr2raw & 0xFF);
      chr3 = isNaN(chr3raw = input.charCodeAt(i++)) ? NaN : (chr3raw & 0xFF);

      enc1 = chr1 >> 2;
      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
      enc4 = chr3 & 63;

      if (isNaN(chr2)) {
       enc3 = enc4 = 64;
      } else if (isNaN(chr3)) {
       enc4 = 64;
      }

      output = output +
      this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
      this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

     }

     return output;
    }
}



// http://web.archive.org/web/20071103070418/mgran.blogspot.com/2006/08/downloading-binary-streams-with.html
//fetches BINARY FILES synchronously using XMLHttpRequest

load_url = function(url) {
    var req = new XMLHttpRequest();
    req.open('GET',url,false);
    //XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
    req.overrideMimeType('text/plain; charset=x-user-defined');
    req.send(null);

    if (req.status != 200){
    alert(req.status);
    return '';
    }
    return req.responseText;
}

    function getDataURI(filename)
    {
    var file =  load_url(filename);
    var uueFile = Base64.encode(file);
    var uri = 'data:application/octet-stream;base64,' + encodeURIComponent(uueFile);
    return uri;
    }

 window.addEventListener("load",
                      function()
                      {
                        var link = getDataURI("foo.pdf");
                        document.getElementById("myDiv").innerHTML += '<a href="' + link + '"><code>' + link +  '</code></a><br><br>';
                      }
Matthew Flaschen
no :( it just seems like this should be possible....
@raj: That's exactly what the headers are for. The response body is the content, the headers are a suggestion what to do with it (e.g. Content-Disposition)
Piskvor
thanks for the solution. I tried using the code. Here is the bottom of the code I used: window.addEventListener("load", function() { var link = getDataURI("http://www.google.com/ads/hunts.pdf"); document.getElementById("myDiv").innerHTML += '<a href="' + link + '"><code>' + link + '</code></a><br><br>'; }</script><body><div id="myDiv">hello</div></body></html>Unfortunately, there was nothing on the html file except the word hello. no pdf. Do I need something else?
in the link i used "http://www.google.com/ads/hunts.pdf".I had http in the front of that link, but SO just converts it to a link without the http.
First of all, you can only do XMLHttpRequest calls on your own server. So copy the PDF to the same server as the HTML page, and try again. If it still doesn't work, enable JavaScript error checking and tell us what errors you get.
Matthew Flaschen
+4  A: 

If you can output the file to the client in base64, you could use data uris to for the download.

location.href = 'data:application/octet-stream;base64,' + appendPDFContentHere
OR
<a href="data:application/octet-stream;base64,appendPDFContentHere">pdf</a>

This will only work in non-IE browsers however but as you requested for firefox, this should work nicely.

EDIT:

Both of the examples below contain the bytes to make a PNG. If you click the first one you can view the image as you normally would in a browser. however, if you click the 2nd link, it will force you to download the image. Save it as a .png and you will see they are the exact same images. The only difference in the two links is the mime type

view image (preview shortened url) -- mime type: image/png

download image (preview shortened url) -- mime type: application/octet-stream

You asked what you put in place of appendPDFContentHere and the answer is the base64-encoded bytes that make up the PDF. I used this online base64 encoder to encode the image used in the example.

fearphage
what should i put in "append PDF content here"?the entire PDF?
or just the url to the pdf?
No, if you just do the URL you can't add the mimetype (application/octet-stream).
Matthew Flaschen
I updated my post to include more detail. I hope this helps.
fearphage
I gave some code below based on this idea.
Matthew Flaschen
A: 

Ummm... not really. The browsers behave differently in different conditions. For example if the user has a PDF reader application that can integrate into the browser (such as Acrobat Reader) the user will not see the save as dialog in most cases. The user has to change the viewer's settings and turn off "browser integration". Alternatively, user should turn off the browser plugin for pdf readers. Its all dependent on the client's environment. There is not much you can do.

Salman A
A: 

"How to force save as dialog box in firefox besides changing headers?"

I have the same question but for saving the file in .html . My requirement is that I generate a new html page (from the currently opened page) on the click of a button and take this new page content and show SaveAs Dialog for it.

Any suggestions please?!