Search code examples
javascripthtmlhttp-postcontent-disposition

Downloadable data link for HTTP POST using JavaScript


I have an HTTP POST REST endpoint that consumes an image and returns an HTML document with pixel data from the image. The HTTP response includes the header Content-Disposition: attachment; filename=Pixels.html so that the browser would prompt for downloading.

I would like to have an HTML/JavaScript (not jQuery) app that

  1. allows me to browse and pick an image (e.g., <input id="fid" name="fid" type="file" />
  2. on clicking a link post the image data to the endpoint and let me download the HTML content to the disk (e.g., <p onclick="javascript: getPixels()">Get Pixels</p>).

How do I go about doing this? I tried the following code:

  function getPixels() {
     var input = document.getElementById("fid");
     if (input.files && input.files[0]) {
        if (typeof (FileReader) != "undefined") {
           var reader = new FileReader();
           reader.onload = function (e) {
              var imgData = e.target.result;
              var postUrl = "./GetPixelsService.svc/image";
              var xhr = new XMLHttpRequest();
              xhr.open("POST", postUrl);
              xhr.setRequestHeader("Content-Type", "image/png");
              //xhr.onreadystatechange = function () {
              //   if (xhr.readyState === 4) {
              //      var res_display = document.getElementById("results");
              //      res_display.srcdoc = xhr.responseText;
              //   }
              //}
              xhr.send(imgData);
           };
           reader.readAsArrayBuffer(input.files[0]);
        }
     }
  }

The following is the HTML blurb that calls the above function.

  <p>
     Upload the image here:
  </p>
  <input id="fid" name="fid" type="file" />
  <!--<button type="submit" onclick="javascript: getPixels()">Get Pixels</button>-->
  <p onclick="javascript: getPixels()">Get Pixels</p>
  <p />
  <hr />
  <p>
     <img id="img2check" src="" alt="" />
  </p>
  <p />
  <iframe id="results" style="width: 100%; border: 0; height: 400px;" src="javascript:;">
     Your browser does not support iframes.
  </iframe>

I am able to pick the response and display it in an iframe, but unable to get the browser to download the content.

Appreciate your help. I have looked at the relevant questions on StackOverflow, but none has helped so far.

Thanks in advance.


Solution

  • Thanks to er-han, the following code achieves the goal.

      <!DOCTYPE html>
      <html>
      <head>
         <meta charset="utf-8" />
         <title></title>
      </head>
      <body>
         <script type="text/javascript">
            function getPixels() {
               showImage();
               var input = document.getElementById("fid");
               if (input.files && input.files[0]) {
                  if (typeof (FileReader) != "undefined") {
                     var reader = new FileReader();
                     reader.onload = function (e) {
                        var imgData = e.target.result;
                        var postUrl = "./SimpleService.svc/image";
                        var xhr = new XMLHttpRequest();
                        xhr.open("POST", postUrl);
                        xhr.setRequestHeader("Content-Type", "image/png");
                        xhr.onreadystatechange = function () {
                           if (xhr.readyState === 4) {
                              var res_url = URL.createObjectURL(new Blob([xhr.responseText]));
                              var lnk = document.getElementById("dlink");
                              lnk.href = res_url;
                              lnk.style.display = "block";
                           }
                        }
                        xhr.send(imgData);
                     };
                     reader.readAsArrayBuffer(input.files[0]);
                  }
               }
            }
    
            function showImage() {
               var input = document.getElementById("fid");
               if (input.files && input.files[0]) {
                  if (typeof (FileReader) != "undefined") {
                     var reader = new FileReader();
                     reader.onload = function (e) {
                        var img_display = document.getElementById("img2check");
                        img_display.src = e.target.result;
                     };
                     reader.readAsDataURL(input.files[0]);
                  }
               }
            }
         </script>
    
         <p>
            Upload the image here:
         </p>
         <input id="fid" name="fid" type="file" />
         <p/>
         <button type="submit" onclick="javascript: getPixels()">Upload</button>
         <p />
         <hr />
         <p>
            <img id="img2check" src="" alt="" />
         </p>
         <p />
         <p>
            <a id="dlink" href="#" download="Data.html" style="display: none;">Download data</a>
         </p>
      </body>
      </html>