Detecting the File Download Dialog In the Browser

14837 ワード

Detecting the File Download Dialog In the Browser回転:http://geekswithblogs.net/GruffCode/archive/2010/10/28/detecting-the-file-download-dialog-in-the-browser.aspx
 
Updated 2011-01-28 to reference the corect question stackover flow.com
Updated 2011-10-02 With a link to a  sample appication github.
Updated 2013-07-01 with corected jQuery Cookie plug-n link and syntax
In the web appication I work on we sometimes need to create PDF documents based on some user input.In most cases,these documents are fairly simple and quick to create,allowing us to create the documentine thein the HTTP reponse.This causes the breowser file download mechaism to kick in allowing the user to save or open the reulting PDF.This appech works great and I think come to be the expected bevitor bevitor for fitworket atworks。
Generating a file,however,can sometimes take a few seconds.This shart duration is not necessarly long enough to juseflody the file generate process(e.g.a service bus,a service burs,a serate prorever.ウェブサイト is long enough that the user waiting for the download may think nothing is happening and atempt to click the「create file」button again.We definitely dot want the user submitting a reest creat the fite the the and the the save。  jQuery Block UI plug-in トdisplay a「please wait」message and prevent further requests from being made from that browser.This works great,but you eventualy need to un-block the UI so that your users can conting dong the fidetwork ftwork。I don’t know of any way javascript tricks to detect when the file download dialog is displayed to the user.Without being able to to to to to to that event,the UI will remand blocked forever,forever,fore the the the the the ustreige the the clearmessage.You could use some kind of time out to autmatrically un-block the page,but in most cases you’d likely end up on-blocking too early or too late.
The re are some ways to work around this by writing the file to disk or some caching mechange and then providing a separate URL endpoint to download the finished file,but these appore require what is,in mya non-trivial amount of server side code to accococompplish.All I really want is a way to let the user know that we’re building their file and to keep them from hitting‘submit’multimes.Inseratimes.Inseradith forching  a question on Stock Overflow (originally found on another not-to-be-named site that scraped stackoverflow.com)where one of the answers presented an interesting idea for soniving this problem.While we can't use javascript to determine when the browser receives a reponse with the「content-disposition:atement」we can use javascript to determine when the brereceives a cookie with a certain name and value.We can add a very minimimaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafor download.Let’s take a look at some code:
The Client Side Setup
The code I’m showng here is adated from ASP.NET Web Forms aplication,but I’ll try to keep it a s a generanic looking as possible as.NET Web Forms appless of the playform you.First,let therst's。
<form id="create_pdf_form">
  <fieldset>
    <legend>Create Customer Info Sheet PDF</legend>
        <div>
          <label id="first_name_prompt_id" for="first_name_input_id">First Name</label>
          <input name="first_name_input" id="first_name_input_id"/>
       </div>
        <div>
          <label id="last_name_prompt_id" for="last_name_input_id">Last Name</label>
          <input name="last_name_input" id="last_name_input_id"/>
       </div>
      <input type="hidden" id="download_token_value_id"/>
      <input type="submit" value="Create File"/>
</fieldset>
</form>
Notice the‘hidden’input field I includ in that form.We’ll use that field to provide a token value to be includ in a cookie in the file download reponse.Now let’s look at the jQuery cothinatwith th th th th th th the  jQuery 1.4.2,the  jQuery Block UI plug-in、and the  jQuery cookies plug-in.
  $(document).ready(function () {
    $('#create_pdf_form').submit(function () {
      blockUIForDownload();
    });
  });

  var fileDownloadCheckTimer;
  function blockUIForDownload() {
    var token = new Date().getTime(); //use the current timestamp as the token value    $('#download_token_value_id').val(token);
    $.blockUI();
    fileDownloadCheckTimer = window.setInterval(function () {
      var cookieValue = $.cookie('fileDownloadToken');
      if (cookieValue == token)
       finishDownload();
    }, 1000);
  }
First,we’re using jQuery to hook into the’submit’event of the HTML form.This will get fired just pror to the form data being submitted to the server.When this happens we’re generant a token valution.Thure starring.Thane starring a.Thore starring.Thore stant。but we do want to try and make it unique per request comming from the same browser,and using the timestamp is a pretty way to this.We tate that token and add it to the form within the the field the the the atekell。
Next,we’re using the jQuery Block UI plug-n to block the user from submitting the form multimes.The behavior of the Block UI plug-i-n is configrable and I encourage to go cheout the  documentation for details on all of the different ways you can customize what message is displayed to the user while the UI is blocked.
With the UI effectively blocked、we use the'window.setInterval'function to create an interval timer.The first argment provided isthe function ththththat t t t to have executed aaaaaaaach interval and the second arggment is how lololong you wantthe theinininininintervavantthe the the forforforforforforforforforwantthe the intervavavavattttttttttttttttttttttttttttttttttttttttwiwiwiwiwiwiwiwiwiwiwiwiwiwi’r.e using the jQuery cookies plugi-in to exmine the value of a cookie named‘fileDownloadToken’.When the value of that cookiemachs the token value aaaaaaawegenetbefore(based on the curretetetetetininininininininininininininindededededededebefore e e e e e e aaaattttttttttttttttttttttwefore e e e e e before e e e e e e e e e e e e e e e e beforfore e e e e e e e e method in a bit.First,let’s see what we need to do on the server side.
The Server Side Setup
Again,I’adappted this example from aparam ASP.NET Web Forms appplication,so the code below is C\21858;,but thisaaaaappshshshwok for just autany web platform.I’tanten out the partthe particout the partororororororororororararararararararararaaaaaaaaaatototototototosasasasasasasasasasasasasasasasasasasasasasasasasasasasasalalalalalalalalalalalatttttttttto appication.
var response = HttpContext.Current.Response;
response.Clear();
response.AppendCookie(new HttpCookie("fileDownloadToken", downloadTokenValue); //downloadTokenValue will have been provided in the form submit via the hidden input fieldresponse.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", desiredFileName)); //desiredFileName will be whatever the resutling file name should be when downloaded

//Code to generate file and write file contents to response
response.Flush();
What I like best abobout thisaaaautaaaautaaaaaathatあなたのパワーgoing to have to write 99%のthe aab ove code code one way the aaaaaaboboboboboboboboboboe aaaatotothe athe aathe athe athe athe athe athe athe aaaaathe aaaaaaathe aaaaaaaaaaathe athe aaaaaathe athe aathe athe aaaaaaathethethethethethethethethe aaaaaaaaaaaaaathe for back on thebrowser while all of the server side code is building the file to be downloaded.Onese the reponse is floushed back to the client,our timer will see the cookie is present and invoke the'finish downlook.tant.
Finishing Up On The Client Side
Onese the expected cookie value appars、all that’s left to do is a little bit of clean up in the'finish Download'function:
function finishDownload() {
 window.clearInterval(fileDownloadCheckTimer);
 $.removeCookie('fileDownloadToken'); //clears this cookie value $.unblockUI();
}
All we’re dong here is clearing out the previousy set interval timer,removing the cookie,and unblocking the UI so that the user can conting dong their work after the y decide what do with the dowfied.we added a line or two to the server side code and a few line s of javascript to accomplash goal of informing the user that we’re working on their file.
I’ve put together a full working sample of this approach in the form of an ASP.NET MVC 3 appication that you check out on github:  https://github.com/appakz/Detect-Browser-File-Download-Dialog-Sample