Firefox 4k XML node limit

June 18, 2008

Did you know that Firefox has a 4096 character limit for XML nodes? I didn’t until today, and it took me quite a while to track it down! Here is the scenario: You make an AJAX request for some data, you then navigate the DOM of the returned XML data and extract the data you’re after. Something like:

function ajaxResponseHander(xml)
{
    var dataNode = xml.firstChild;
    var data = dataNode.firstChild.nodeValue;
    // now do something with the extracted data...
}

This works fine in IE, Safari, and Opera. It’ll even work fine in Firefox. That is until your data exceeds 4k. At that point you’ll only get the first 4096 characters. This is because Firefox splits any node that exceeds 4k into multiple nodes. Say, for example, you have a node with 6316 characters then you will end up having a node with the following properties:

dataNode.childNodes.length == 2;
dataNode.childNodes[0].length == 4096;
dataNode.childNodes[1].length == 2220;

Fortunately Firefox provides the textContent attribute, so we can just use:

var data = dataNode.textContent; // data.length == 6316

Although because IE doesn’t support the textContent attribute, we’re better off writing a function:

function getNodeText(xmlNode)
{
    if(!xmlNode) return '';
    if(typeof(xmlNode.textContent) != "undefined") return xmlNode.textContent;
    return xmlNode.firstChild.nodeValue;
}

I hope I’ve saved someone some pain!

28 Comments »

  1. > I hope I’ve saved someone some pain!

    You did. Thanks.

    Comment by Tmk — July 5, 2008 @ 7:05 am

  2. Thanks a lot!!
    It’s very helpful for me.

    Comment by Doris — July 11, 2008 @ 8:46 am

  3. Man, you saved my life.

    Comment by RZ — July 25, 2008 @ 7:47 pm

  4. Thank you a lot! This is exactly my situation.

    Comment by sheich — August 5, 2008 @ 6:37 am

  5. Which version of Firefox did you have this problem with?
    I just tried putting a large node thru my own nodetext
    function listed here, and it looked ok in Firefox 3.0.1.
    Just wondered what could be causing the difference(?)
    (note the “xmlnode.text” for older IE’s which works,
    but the output format can be different).

    mark
    ajamyajax.com

    aja_getXmlNodeText = function(xmlnode) {
    try {
    // Firefox, etc.
    if (xmlnode.textContent) {
    return xmlnode.textContent;
    }
    // older MS Internet Explorer
    else {
    return xmlnode.text;
    }
    }
    catch (e) {
    return null;
    }
    }

    Comment by Mark — August 25, 2008 @ 8:03 pm

  6. Oops, forgot to the last post’s code but you get the idea, I’m sure.

    Comment by Mark — August 25, 2008 @ 8:05 pm

  7. that’s <pre> format, lol. sorry.

    Comment by Mark — August 25, 2008 @ 8:06 pm

  8. Hi Mark,

    Thanks for your comments. I fixed the formatting on your comment, and I also removed the example 4k node :)

    The problem exists in ALL firefox versions. Your code will work perfectly well because you’re using node.textContent, which was the solution I documented.

    The problem only occurs if you try to access the content with node.firstChild.nodeValue. That works in all browsers other than Firefox, which just returns the first 4k.

    Comment by admin — August 25, 2008 @ 8:12 pm

  9. Thanks, I’ll keep that in mind. And I’m glad you removed my test node data (sorry, I got carried away there), but here is my XML test file structure in case you think it would help anyone else in their “large node” tests.

    However, it’s your blog so keep or delete as you see fit, of course. :) Have a good one.

    <?xml version=”1.0″ encoding=”ISO-8859-1″?>
    <root>
    <nodetest>
    <smallnode>
    This is a small node
    </smallnode>
    <largenode>
    This is a large node

    (> 4k worth of data here)

    last line here…
    </largenode>
    </nodetest>
    </root>

    Mark

    Comment by Mark — August 25, 2008 @ 8:56 pm

  10. Now that I’m on the same page as to what the problem is :) , here is another suggested workaround… Avoid using firstchild altogether. The recursive call below is the trick — it processes thru all the large node pages back-to-back so you can combine them however you want (just lists the data here).


    // just my start-up code here, get there however you like:
    allnodes = xmlDoc.getElementsByTagName('*').item(0);
    listNodes(allnodes);

    // recursive listing function
    function listNodes(nodes) {
    for (var i=0; i < nodes.childNodes.length; i++) {
    var node = nodes.childNodes[i];

    if (node.nodeType == 1) {
    document.write(node.nodeName + "<br/>");
    }
    else if (node.nodeType == 3 || node.nodeType == 4) {
    document.write(node.nodeValue + "<br/>");
    }

    if (node.hasChildNodes()) {
    listNodes(node);
    }
    }
    } // end of listNodes

    Also, you can substitute the ‘*’ with ‘yourNodeNameHere’ and this node processor will start there. Just for anyone who doesn’t know that already.

    Hope this helps.
    Mark

    Comment by Mark — August 26, 2008 @ 3:28 pm

  11. there’s that <pre> thing again, admin..
    oh well, i tried.

    Comment by Mark — August 26, 2008 @ 3:31 pm

  12. This just saved me after over 2 hours of trying to find out why my XML text was getting truncated. Thank you for posting such a useful article!

    Comment by Jason — September 9, 2008 @ 11:31 pm

  13. Thanx a lot !
    Saved a lot of pain, indeed.

    Comment by Claus — October 23, 2008 @ 10:55 pm

  14. Fantastic help, thank you very, very much! Had to work a bit to integrate this with my SOAP client but after a bit of messing around it came good, never would have gotten there without this though! Stupid 4K limits!

    Comment by Stubby — November 5, 2008 @ 8:48 pm

  15. Awesome! Exactly the information I was looking for. you need a paypal donate button on this page ;)

    Comment by DonT — November 17, 2008 @ 5:28 pm

  16. Good, help me a lot, thanks

    Comment by stanley — November 27, 2008 @ 2:42 am

  17. Sweet ! Straight to the point and fixed my problem. Top stuff, nice site.

    Comment by Scott — May 25, 2009 @ 12:24 pm

  18. Really helpful. Lots of thanks. You saved my life!!

    Comment by Shimon — June 9, 2009 @ 9:50 am

  19. Thanks Mate.
    You really saved my project!
    If you’re ever downunder. The beers are on me!

    Comment by Langdon — July 10, 2009 @ 7:29 am

  20. Thanks to you! Nice tip!

    Comment by romero — July 16, 2009 @ 12:06 pm

  21. Thanks man!
    We just found out about this issue. Something was parsing good in IE and Firefox when suddenly, as data was growing, it no longer worked right in Firefox…how can it be than our hero browser doesn’t work anymore while IE still does?

    Now we just created a function similar to yours to get the text properly.

    Thanks dude!

    Comment by Nelson — September 17, 2009 @ 9:32 pm

  22. thx.

    Comment by Jose — October 13, 2009 @ 3:07 pm

  23. After battling for some while with a fairly complex AJAX app, I thought I was in the home stretch, when – BAM! – I hit this problem with Firefox. I had diagnosed this to the point of realizing there was 4K truncation, and that it happened only in FF and not in IE. However, I had no idea what to do about this and tried a desperate Google search. Fortunately, I came up with your page right away, and I quickly added the fix to my code. It works perfectly.

    Thank you very, very much!

    Comment by Lisa — October 20, 2009 @ 3:13 am

  24. Did Firefox always do this?

    Anyway, I only just noticed it, so thanks for the easy-to-find solution!

    Comment by John (London) — March 16, 2010 @ 12:23 pm

  25. Hi John,

    As far as I know Firefox has always behaved this way. It’s an annoying when you first come across it, but fortunately it isn’t too hard to work around!

    Cheers, Ben

    Comment by Ben — March 16, 2010 @ 5:38 pm

  26. > I hope I’ve saved someone some pain!
    You did again.
    Thanks!!

    Comment by Hsien — March 17, 2010 @ 5:45 am

  27. Thank you very much!!!!!!!!!!!

    Comment by Júlio — April 1, 2010 @ 6:17 pm

  28. Thank you. Really helpful.

    Comment by Chaitanya — August 5, 2010 @ 8:18 am

RSS feed for comments on this post. TrackBack URL

Leave a comment