Note To Self: Prevent Uploads Hanging In Safari

I always learn a lot reading other people’s code. (Admittedly the lesson is sometimes to run in the opposite direction as fast as possible.) This morning I was looking at Basecamp’s file upload interface which is lovely and clean.

In each file’s form’s onsubmit handler I noticed a call to closeKeepAlive(). Here’s what it looks like:

/* A pretty little hack to make uploads not hang in Safari. Just call this
 * immediately before the upload is submitted. This does an Ajax call to
 * the server, which returns an empty document with the "Connection: close"
 * header, telling Safari to close the active connection. A hack, but
 * effective. */
function closeKeepAlive() {
  if (/AppleWebKit|MSIE/.test(navigator.userAgent)) {
    new Ajax.Request("/ping/close", { asynchronous:false });
  }
}

Nice.

Andy Stewart, 17 August 2007

Posted in Notes To Self, Rails


  1. Thank you very much!

    Olly
    22 August 2007
  2. I installed this workaround and I noticed that I was still seeing the Safari/Webkit 'hang problem'. After a bit of investigation I think I've found the problem.

    I had a disable_with value set on my submit tag which itself calls this.form.submit() which appears to override any other onsubmit handler you define.

    For now I have removed the disabled_with tag but I'd be interested in a solution which would allow me to keep the disabled behaviour.

    Olly
    24 October 2007
  3. I suggest overriding the FormTagHelper's submit_tag method, or perhaps writing your own helper method based on that one, to give you the behaviour you want.

    You could have it recognise a :keep_alive option and do the right thing.

    Andy Stewart
    24 October 2007
  4. As of changeset 6134 a form using :disable_with will trigger its onsubmit handler if available.

    Rather than having your :disable_with value call this.form.submit(), wouldn't it be better to let the form take care of it as per 6134?

    Andy Stewart
    06 November 2007

Have your say

You can use Markdown in your comments. If you want to post code, do this:

<pre><code class="ruby|javascript|css|html">your code here</code></pre>

Thanks!