1

Is there any chance to handle when form submit finished(ok or error)? I want to upload images or mulitpart data without javascript libraries. For example, user clicks submit button, after uploading data server responds with error or success response. Depending on that result I need to do something. Here is example form:

<form method="post" enctype="multipart/form-data" action="/upload_file">
    <input type="file" name="upload_image" />
    <input type="submit" value="Submit" />
</form>
4

2 回答 2

3

Since I've not access to the server side, I need to solve this problem on the client side. That's why I couldn't use cookies.
I did these steps to achieve success (I used jQuery to create/bind element/events. I didn't use AJAX to send form data):

1. I have iframe in my HTML (pay attention, there is no iframe in HTML):

<form id ="send_message_form" target="multipart_uploader_iframe" 
    method="post" enctype="multipart/form-data" action="/upload_file">
    <input type="file" name="upload_image" />
    <input type="submit" value="Submit" />
</form>


2. I created iframe when submit clicked (I tried to avoid unnecessary onload event firing). Notice, after adding iframe to body, I added attribute onload. Because if I add onload attribute while creating iframe, it instantly fired when I append iframe to body. Now closePopup is called once when server responded.

$('#send_message_form').submit(function() {
    var customIframe = $('<iframe></iframe>');
    customIframe.attr({
      'id': "multipart_uploader_iframe",
      'name': "multipart_uploader_iframe"
    });

    $('body').append(customIframe);
    customIframe.attr({
      'onload': "closePopup();"
    });
    return true;
});


3. When server responds with responseText (if it returns with text/plain type), responseText will be put in iframe body. Then iframe's onload event fires (of course our closePopup function). In my case server responded with OK or other error text:

// Generated by CoffeeScript
window.closePopup = function() {
    var error, response, _ref, _ref1;
    setTimeout(function() {
      return $('#multipart_uploader_iframe').remove();
    }, 500);
    try {
      response = (_ref = (_ref1 = frames['multipart_uploader_iframe']) != null ? 
        _ref1.document.getElementsByTagName("body")[0].innerHTML : void 0) != null ? _ref : "";
      if (response.indexOf("OK") !== -1) {
        // close here your popup or do something after successful response
        alert('Message has been sent successfully.');
        return $(".popup").dialog('close'); 
      }
    } catch (_error) {
      error = _error;
      throw new Error(error);
    }
    return alert("Error occurred while sending message.");
};

I'm really inspired by this article. I hope this helps someone who has the same problem.

PS: It worked on IE8

于 2013-05-08T15:59:10.340 回答
1

One non-ajax option is to have a hidden iframe on the page with a name, and to set the target action of your form to the name of that iframe. Have the server respond with a cookie that's specific to the form (you might even pass in an id the server should use as the cookie name), then on form submit start polling to see if that cookie exists. When the cookie arrives, it means the server has replied to the form post in the iframe. You can either put the success/failure information in the cookie itself, or put it in the document that ends up in the iframe and have your client-side code scrape it from there. Then take appropriate action.

E.g., in pseudo-code:

On The Client                  On The Server
---------------------------    ---------------------------
1. JS assigns ID to form
2. User submits form
3. JS handles submit event,
   starts polling for the
   cookie with the relevant
   ID
                               4. Receives and processes the form
                               5. Responds with success/failure and
                                  cookie
6. JS polling sees cookie,
   reads success/fail from
   cookie or document in
   iframe
7. JS does something appropriate
   with success/fail info

I first came up with this technique to answer this other question here, immediately used it on a project, and it works a treat. In the case of that question, we were dealing with something that would return a document to download (Content-Disposition: attachment) (I used it to show a "Building your document" div and then replace that with success/failure when the cookie arrived), but it works perfectly well if you're doing something else.

于 2013-05-07T07:20:08.427 回答