8

So I know there have been a number of similar posts, but I think this is enough of a variation to warrant its own question:

I am building an XLS exporter in PHP and jQuery. I am trying to POST an array with jQuery (which I believe is going to be too long as a GET querystring), and use it to generate an XLS file on my server, which the user can then download.

I have used hidden iframes in the past to accomplish this, but since they just redirect to a url, this requires me to use GET, which makes me nervous.

My question is then: how do I store those files on my server and link to them if they're being generated dynamically, potentially by multiple users? Would a hidden iframe link to a separate PHP script that locates THEIR file based on a session ID or something like that?

Thanks in advance for any guidance here on what I'm sure gets asked all the time :)

Community
  • 1
  • 1
Trafalmadorian
  • 2,498
  • 2
  • 21
  • 13

2 Answers2

9

It is possible to POST to a hidden iframe. Therefore, you don't need to worry about the length of the query string; you will post the key/value pairs which will generate your XLS file and subsequently force the file download to the browser.

<form method="post" action="/download/xls" target="download_xls"> 
  <fieldset>
    <label>Key 1:</label>
    <input type="text" name="key_1" />
  </fieldset>

  <fieldset>
    <label>Key 2:</label>
    <input type="text" name="key_2" />
  </fieldset>

    <fieldset>
            <input type="submit" value="Submit" /> 
    </fieldset> 
</form>

<iframe id="download_xls" name="download_xls" width="0" height="0" scrolling="no" frameborder="0"></iframe>

UPDATE A quick Google search turned up this article: http://particletree.com/notebook/ajax-file-download-or-not/

Basically, the suggestion is to POST your form to the current page and respond with a file download. This alternative might be good enough for you.

simeonwillbanks
  • 1,459
  • 16
  • 18
  • Very cool idea, but unfortunately, the target attribute is deprecated in form elements, so I don't know if that would be a safe solution. – Trafalmadorian Aug 31 '10 at 22:10
  • Fascinating. I'm going to go try it out right now...if it works, I'll accept your answer :) – Trafalmadorian Aug 31 '10 at 22:16
  • You are correct. It is deprecated in HTML 4.1 and XHTML 1.0. However, its valid in XHTML 1.0 Transitional, and it is still supported by most major browsers. http://www.w3schools.com/TAGS/att_form_target.asp – simeonwillbanks Aug 31 '10 at 22:17
  • UNFRIGGINBELIEVABLE!!!!!! Who would have guessed it could be this simple! Thanks so much for the great research into this. All I had to do was create a form, change the value of its input and submit it with jquery! – Trafalmadorian Aug 31 '10 at 22:24
  • Yeah just a quick summary from a few months later...the target attribute isn't needed on the form, you can do it with just the action attribute! – Trafalmadorian Oct 27 '10 at 20:21
5

This seems like it should be pretty simple, but it all depends on where you're putting those XLS files you're generating. If you're intending that the response to the post should be a "Save File" dialog — that is, the file itself — then all you have to do is make sure the "Content-Disposition" header is set to "attachment", and then stream out the file contents.

If you're going to generate the file and keep it around, well you're going to have to store it somewhere with an identifier. In that case, you'd just respond with an ordinary page that's got a "download" link, such that that link includes the file identifier. That can trigger either a GET or a POST, and the server would respond to that pretty much as I described above.

A hidden <iframe> doesn't really figure into this, in my opinion.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • Thanks so much for the response. Ideally I wouldn't keep them around, and would just link the user to a "Save File" dialog. However, if I do that, I have to first POST data from their client and generate the file FROM that data, and link them back to it...which seems like it would force me to keep it around on the server once it's been generated. Circular logic, I know :) – Trafalmadorian Aug 31 '10 at 22:04