#842 ✓invalid
Christian Walde

Ajax.Updater fails silently in IE when the response contains <form>

Reported by Christian Walde | October 23rd, 2009 @ 06:57 PM

In IE it is impossible to insert HTML code with a into the innerHTML of an element. It silently fails with an undefined exception.

Since Ajax.Updater can only insert the response via innerHTML so far, it simply cannot insert any content with in IE and fails silently.

Comments and changes to this ticket

  • Tobie Langel

    Tobie Langel October 23rd, 2009 @ 07:58 PM

    • State changed from “new” to “help_request”

    Sorry you're having trouble.

    Lighthouse is reserved for development purposes. Please direct assistance requests to the mailing list or IRC channel.

    Thanks for your understanding.

  • Christian Walde

    Christian Walde October 23rd, 2009 @ 08:09 PM

    I'm not sure how this is a help request. I've already worked around it. This is a description of a bug that Prototype exhibits on IE.

    Since I already took the time and figured out exactly why it happened I figured it would be enough to describe these details in order for you to either implement a workaround or at the very least amend Prototype so that it dumps a sensible error message.

    Do you need anything else from me or is this just the kind of issue where the stance is "tough luck"?

  • Tobie Langel

    Tobie Langel October 23rd, 2009 @ 08:52 PM

    • State changed from “help_request” to “bug”
    • Tag cleared.

    Sorry, but the FORM tag disappeared from your message (had to check the source to understand what was going on). It just looked like you were claiming that nothing worked in IE at all. Which is usually the sign of a beginner needing assistance.

    Sorry for the misunderstanding. Of Course, patches, failing test cases, etc., are welcomed.

  • Tobie Langel

    Tobie Langel October 23rd, 2009 @ 08:53 PM

    Please include Prototype version number, etc. (I was pretty sure we had fixed that.)

  • Christian Walde

    Christian Walde October 24th, 2009 @ 07:57 AM

    Haha, alright, that explains that. :)

    Version is this:
    /* Prototype JavaScript framework, version 1.6.1 * (c) 2005-2009 Sam Stephenson

    Offending line is 1890 in this function:
    function update(element, content) {
    in this file:
    http://greenphyl.cirad.fr/v2/js/prototype.js

    Not exactly a test case, but more of an explanation as to what i tried to accomplish:
    http://greenphyl.cirad.fr/v2/cgi-bin/family.cgi?id=20939
    Click on "Family composition"
    Click on any bar in the flash
    A table gets loaded below via the function 'display_sequence_table' in 'js/greenphyl.js'.

    Originally the html code that gets loaded had the form tags right inside it. That broke.

    Now the form tags are around the 'sequence_table' div, that works.

  • Tobie Langel

    Tobie Langel October 24th, 2009 @ 04:25 PM

    Could you maybe provide a minimal failing test case?

    That would help.

  • Christian Walde

    Christian Walde October 24th, 2009 @ 07:05 PM

    I hope this helps: http://drop.io/prototype_testcase
    It needs to be loaded from a web server, as IE will otherwise refuse to run the ajax stuff.

    Key seems to be the "form -> div -> innerhtml -> form" structure, which will fail under IE, even though: "form -> div -> -> form -> innerhtml -> div" will work fine.

  • Christian Walde
  • Tobie Langel

    Tobie Langel October 24th, 2009 @ 11:13 PM

    Is ajax really necessary?

  • John-David Dalton

    John-David Dalton October 25th, 2009 @ 12:20 AM

    I found a few issues with your use case.

    First, you are setting an undeclared variable in your simple_ajax it should be var dsException = "".

    Second, prototype.js should be loaded before the code that requires it. It doesn't really matter because of
    how you are using it but it's something I prefer.

    Third, you are returning full html documents in your response and then attempting to set a div or
    form element.innerHTML = '<?xml version="1.0" encoding="utf-8" ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> ...';

    The fact that it works is probably a fluke in the browsers attempting to make chicken salad out of chicken shit.

    Fourth, I have always wanted to use that chicken salad expression in a discussion about code. :D

  • John-David Dalton

    John-David Dalton October 25th, 2009 @ 12:37 AM

    Here is your test re-done to work properly.
    It no longer is trying to created nested form elements which is invalid html.
    http://www.w3.org/TR/html401/interact/forms.html#h-17.3

    http://dl.getdropbox.com/u/513327/mintest/index.html

  • Tobie Langel

    Tobie Langel October 25th, 2009 @ 01:28 AM

    Thanks for your cleanup JDD. That doesn't really answer my initial question, though: can we reproduce the issue with a minimal amount of code:

    <!doctype html>
    <html lang="en">
    <head>
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <script src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js" type="text/javascript"></script>
    </head>
    <body>
      <div id="foo"></div>
      <script type="text/javascript" charset="utf-8">
        $('foo').update('<form action="" method="get"></form>');
      </script>
    </body>
    </html>
    

    I don't have IE handy right now, but does the above fail?

  • John-David Dalton

    John-David Dalton October 25th, 2009 @ 01:45 AM

    Tobie, the cause of the error which can be seen in Christian Walde's test case http://drop.io/prototype_testcase
    is the attempt to set invalid html. If done properly there is no issue as my test case showed. Both test cases have already been provided. There is nothing more you need. The issue is caused by invalid use and is not a bug in Prototype.

  • Tobie Langel

    Tobie Langel October 25th, 2009 @ 01:56 AM

    • State changed from “bug” to “invalid”

    Oh, OK. Thank you for clarifying. I'm closing this as invalid, then.

  • Christian Walde

    Christian Walde October 25th, 2009 @ 08:29 AM

    To answer in order (And I really hope before answering any of the points here, you read all of them, as they are interlocked to some degree):

    Is ajax really necessary? Yes, this is a project I inherited from a client and I am limited in how much I change it. A requirement for this particular feature was not to use iframes.

    JDD The first two points are merely style points. If Javascript had any syntax checking at all I would've changed the first one before and I've taken note of the second one. They are irrelevant to the issue at hand though.

    returning full HTML documents Also irrelevant, as that is not what happens in the original version of the minimal test case which also exhibits this behaviour. This is something that only happens because the online version runs on the host of a friend of mine, which wraps everything with Mason automatically.

    test re-done to work properly. No, it is not. The form element wrapping the body of the document is necessary, as that is something stipulated by my client. You assume too much.
    Also, for what it's worth: All elements of that work entirely fine in IE, FF and Opera, with the single exception that IE balks when the inner form is loaded into innerHTML.

    invalid use Mind you, invalid use that works perfectly fine everywhere, excluding very small edge case on IE.
    Additionally, before yesterday I wasn't even aware that there was invalid HTML going on, as no checks in any browser, nor any validator ever pointed this out.

    Now, before I come to the last part, I need to repeat this: I have already fixed the issue in a manner that is satisfactory for me and my client and works on all target platforms with no hassle. As such I could not care less in as far as my problem is concerned, as there is none anymore.

    Although there does seem to be a method, involving creating an object outside the DOM, inserting into its innerHTML and then inserting that object into the DOM; I do agree that there is no need for you to explicitly fix this. However:
    There is still the issue that Prototype by default fails silently on this when using AJAX. The only path towards getting any admission of an error happening out of it is, in my opinion, arcane. And in the end, that error message is useless from any angle and does nothing to point at what the actual issue is.

    I think the proper thing here to do would be to explicitly catch this kind of thing and inform the developer that they are attempting to create invalid HTML. I'm sure it is obvious how this will have benefits to everyone involved and even those not involved.

    As for a final minimal test case, this is how it would be:

    <html>
    <head>
      <script src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js" type="text/javascript"></script>
    </head>
    <body>
      <form>

    &lt;div id=&quot;foo&quot;&gt;&lt;/div&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;
      $('foo').update('&lt;form&gt;');
    &lt;/script&gt;
    
    
    
    
    </form> </body> </html>

    (IE doesn't particularly care about what's being inserted, it fails as soon as a starting form tag is completed.)

  • John-David Dalton

    John-David Dalton October 25th, 2009 @ 08:48 AM

    Your case still shows you trying to add a form within a form.

    Paste this into the input box and click the "check" button
    http://validator.w3.org/#validate_by_input

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <title>x</title>
    </head>
    <body>
      <form action="foo">
        <div>
          <form action="bar"></form>
        </div>
      </form>
    </body>
    </html>
    

    The fact that other browsers are auto-correcting the invalid HTML is not a Prototype issue.
    Ajax silently failing is though and it's already been posted:
    Rethrow errors in ajax callbacks - ticket 634

  • Christian Walde

    Christian Walde October 25th, 2009 @ 09:07 AM

    Trick question: Exactly how many people do you know who insert all possible variants of their AJAX content manually into the receiving document and then manually verify that?

    I realize that the HTML is invalid, I am not contesting that. But there is no reasonably expectable way of this kind of problem ever being found with normal error checking and/or knowing in advance what it actually is. Further: There is no auto-correcting going on. Even in other browsers and even in IE it works out as form within a form and both still work.

    Also, you missed the point where I didn't say that silently failing is the main issue, but that even when you get out some sort of error message it's completely useless.

    Come on, I don't think I wrote the previous post this obtusely.

    As an aside: That bug talks about onCreate, where this problem occurs in onSuccess. I have no idea about the guts of Prototype as I'm not really a JS developer, but I think fixing the former wouldn't touch the latter?

  • John-David Dalton

    John-David Dalton October 25th, 2009 @ 09:22 AM

    This test shows that at least FF 3.5.1 does indeed auto-correct the HTML:
    http://dl.getdropbox.com/u/513327/mintest/fail.html

    Thanks again.

  • Christian Walde

    Christian Walde October 25th, 2009 @ 09:33 AM

    Ok, got that one wrong. Confuses me though why it still works correctly then.

  • Tobie Langel

    Tobie Langel October 25th, 2009 @ 04:57 PM

    Christian, just to clarify a small number of points

    1. My suggestion was not for you to avoid using Ajax in your project, but to provide a minimal testcase where the bug could be reproduced. given that the bug concerned insertion of a string (the HTML returned by the server), it appeared that using ajax was not required in your testcase.

    2. Like every other framework out there, Prototype only supports valid HTML. There's a reason to that, 99% of the case, bugs come from invalid HTML (which is the case for you here again).

    3. There is indeed a mechanism in Prototype's Element#update method which makes it possible to insert form elements in IE.

    The solution to your issue therefore is to request valid markup only. Both in your initial page and in the responses returned by your ajax requests.

    If you have further issues, please do not hesitate to ask about them on our mailing list or IRC channel.

    Thanks for your understanding.

    Tobie

  • Christian Walde

    Christian Walde October 25th, 2009 @ 05:29 PM

    I am thinking you are misunderstanding what I am saying or did not read everything I posted. I could write a lot of words now, but instead am gonna make it a bit shorter. You sound like you are saying:

    "Prototype does not need to return a human-readable error pointing out the use of invalid HTML when it gets an exception caused by invalid HTML, since it does not support invalid HTML."

    Did I get your meaning right there?

  • John-David Dalton

    John-David Dalton October 25th, 2009 @ 06:21 PM

    Please troll somewhere else. We have thoroughly addressed your issue and pointed to similar tickets regarding throwing errors for ajax callbacks. Please direct further correspondence to the mailing list. Thanks.

  • Christian Walde

    Christian Walde October 25th, 2009 @ 06:29 PM

    JDD: I was not adressing you and I can assure you I am not trolling in the least. Please do not devolve into ad hominems.

    As for the similar ticket: I already mentioned that to me it looks like it is a different issue, dealing with a different part of the AJAX handler.

  • Tobie Langel

    Tobie Langel October 25th, 2009 @ 07:09 PM

    Christian, I understand your issue perfectly.

    You would like to have Element#update (which is what Ajax.Updater uses behind the scene) throw a helpful error when trying to insert invalid markup.

    The errors thrown by the browsers (if any) being inconsistent across browsers, unidentified and not specified in any specification, how could Prototype possibly identify them?

  • Christian Walde

    Christian Walde October 25th, 2009 @ 07:49 PM

    Tobie, thank you for understanding. That is very much appreciated!

    In this case I think it would be safe to say that there are two viable routes:

    1. Focus on this specific case: If we're running in IE, and we get an "Unknown runtime error" with the specific code that is generated by this (( -1 * 2^31 ) - 1) and there is "<form" somewhere in the input, let the user know that the browser generated an unknown error and that it might be caused by invalid HTML involving a form nested inside a form.

    2. Focus on the general case: If we get an "Unknown runtime error", let the user know that the browser generated an unknown error and that it might be caused by invalid HTML.

    I understand that with the current browser implementations it is impossible to say "this is exactly this" under the given circumstances, but merely suggesting that as a possible cause would be of value.

  • Tobie Langel

    Tobie Langel October 25th, 2009 @ 11:23 PM

    The first option unfortunately opens a huge can of worms. Why handle this specific case and not others? Where should the line stop? Currently there's a very clear boundary. Your HTML, CSS and JavaScript must be valid code. That must absolutely stay if we want the Prototype code base to stay lean and focused.

    The problem with your second option is that we would be suggesting a reason to a particular error which might be completely wrong. (There's also other practical issues with error handling in IE.)

    In short, I don't see this being a good fit for Prototype at all. Sorry. :-/

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

The Prototype JavaScript library.

Shared Ticket Bins

Pages