Closed Bug 249843 Opened 20 years ago Closed 17 years ago

Problems with XMLHttpRequest after replaceChild() and close()

Categories

(Core :: XML, defect)

x86
Windows XP
defect
Not set
normal

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: roberto.buratti, Unassigned)

Details

Attachments

(3 files)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7) Gecko/20040614 Firefox/0.9
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7) Gecko/20040614 Firefox/0.9

I have a window that opens a second window via window.open(). The second window
calls a function window.opener.callback() that the first window implements in a
<script> tag. The arguments to this function are an ID and a chunck of HTML. The
callback function in the first window use an hidden DIV to parse the chunck of
HTML (via .innerHTML) and to build an HTMLElement. After this, it replaces the
node having the given ID with the newly generated element. Now the second window
(after having called window.opener.callback(...)) close (via window.close())
All seems to work great. But, if an event raised by this element tries to create
a new XMLHttpRequest and to open any URL, the call fails with the following
error: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE)
[nsIXMLHttpRequest.open].

Reproducible: Always
Steps to Reproduce:
1) put this in a file called "mozilla1.htm":
-------------------------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
	<body>
		<input id="cmdWork" type="button" value="this works" onclick="doit()"/>
		<input id="cmdPopup" type="button" value="popup" onclick="openPopup()"/>
		<div id="divContainer">
			now empty
		</div>
		<div id="divDebug">
		</div>		
	</body>
	<script language="javascript">
		var m_oParser = document.createElement("DIV");
		m_oParser.style.height = 0;
		m_oParser .style.width = 0;
		m_oParser .style.position = "absolute";
		
		function doit()
		{
			var oXMLHTTP = new XMLHttpRequest();
			try {
				alert(oXMLHTTP.constructor);
				oXMLHTTP.open("POST", "/", true);
			} catch (e) {
				alert(e.message);
				document.getElementById("divDebug").innerHTML = e.message;
			}
		}
		function openPopup()
		{
			window.open("mozilla2.htm");
		}
		function callback(_oMessage)
		{
			//alert(_oMessage.id);
			//alert(_oMessage.param1);

			var oOldNode = document.getElementById(_oMessage.id);

			m_oParser .innerHTML = _oMessage.param1;
			var oNewNode = m_oParser.childNodes[0];
			
			oOldNode.parentNode.replaceChild(oNewNode, oOldNode);
		}
	</script >
</html>
-------------------------------------------------------------

2) put this in a file called "mozilla2.htm"
-------------------------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
	<body>
		<input id="cmdKaboo" type="button" value="callback" onclick="crashIt()"/>
	</body>
	<script language="javascript">
		function crashIt()
		{
			var oMessage = {id:'divContainer',param1:'<div id="divContainer"><input
id="cmdCrash" type="button" value="this crashes" onclick="doit()"/></div>'};
			window.opener.callback(oMessage);
			window.close();
			//window.setTimeout("window.close()", 10);
		}
	</script >
</html>
-------------------------------------------------------------

3) open mozilla1.htm
4) try the button "this works". It should display a message box with the string
"XMLHttpRequest"
5) click the button "popup". It should open the second window.
6) On the second window click the button "callback". It should close this window
and display a new button on the first window.
7) Now try: "This works" does effectively continue to work, but if you click
"this crahes" you should get the error reported.
Actual Results:  
It seems the object I created with

var oXMLHTTP = new XMLHttpRequest();

is not an istance of XMLHttpRequest ??! :-( Note that the problem occurs IIF (if
and only if!) the second window closes. Otherwise all goes well...


Expected Results:  
It should perform like the button "this works". No?...

None.
Summary: Problem with Problems with XMLHttpRequest after replaceChild() and close() → Problems with XMLHttpRequest after replaceChild() and close()
I am experiencing a similar problem.  It appears that an
XMLHttpRequest object fails after a document.body.appendChild is
performed.  In IE, the callback is called once with a readyState of 1,
2, 3, and then 4.  In FireFox 0.9.3, the same pattern occurs during
the first request, but after appendChild is called, all I get is TWO
callbacks with a readyState of 1.

One can hack around the problem by creating a new XMLHttpRequet object
after every appendChild.  I have attached a simple webapp that
demonstrates the problem.

John

<script type="text/javascript">
// FireFox fails if an attempt is made to reuse a connection.
var firefoxhack = true;
var getconn = new XMLHttpRequest();
function get() {
    getconn.open("GET", "server", true);
    getconn.onreadystatechange=function() {
	if (getconn.readyState == 4) {
	    if (getconn.status == 200) {
		insertText(getconn.responseText);
		if (firefoxhack)
		    getconn = new XMLHttpRequest();
		get();
	    }
	    else {
		insertText("Fatal error--disconnected.");
	    }
	}
    };
    getconn.send(null);
}

function insertText(data) {
    var text = document.createTextNode(data);
    var par = document.createElement("P");
    par.appendChild(text);
    document.body.appendChild(par);
    window.scrollBy(0, 100);
}
</script>

</head>
<body onload="get()">
<h1>ChatLet Transcript</h1>
</body>
</html>
(In reply to comment #4)
>
> [...] It appears that an
> XMLHttpRequest object fails after a document.body.appendChild is
> performed.  In IE, the callback is called once with a readyState of 1,
> 2, 3, and then 4.  In FireFox 0.9.3, the same pattern occurs during
> the first request, but after appendChild is called, all I get is TWO
> callbacks with a readyState of 1.
>
First, I use replaceChild(), not appendChild() but the bug could be related to
both. Then, after this I get an exception on every attempt to call the open()
method: it never reaches the readyState 1.
> 
> One can hack around the problem by creating a new XMLHttpRequet object
> after every appendChild.  I have attached a simple webapp that
> demonstrates the problem.
>
If you look at my code, I alreay use a fresh new connection every time, but this
doesn't seem to hack the problem (at least in my expample...). 

:-(
Rob
I can reproduce this beg every time by spawning a popup window
    window.open('LoadScoreType.aspx', 'ScoreType',
'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=1,width=325,height=200,left=400,top=300');

if that window calls any script on the opener
    window.opener.AddScoreType(scoreValue);

something changes so that any subsiquent calls to XMLHttpRequest.open() will
only work if the popup window remains open.

if the popup is closed any calls to XMLHttpRequest.open() return this error
    [Exception... "Component returned failure code: 0x80004005
(NS_ERROR_FAILURE) [nsIXMLHttpRequest.open]"  nsresult: "0x80004005
(NS_ERROR_FAILURE)"  location: "JS frame ::
http://localhost/XmlFrame/XmlFrame.js :: CallPage :: line 71"  data: no]

line 71 is my XMLHttpRequest.open() call

69			req.onreadystatechange	= ProcessPage;
70			try{
71				req.open(method, url, true);
72			}catch(e){
73				alert(e);
74			}
75			req.send(content);

I'm getting what I think is the same problem when I have a dynamically-created
iframe perform a callback on its parent, but only AFTER the iframe has been
removed (using removeChild()). If you leave the iframe in place, the
XMLHTTPRequest works fine.

I've created a reduced test case at:

http://the-stickman.com/files/mozilla-iframe-bug/ 

Source code available at:

http://the-stickman.com/files/mozilla-iframe-bug/test-iframe-xhr.zip

Tested on Firefox 1.0.4. Haven't tried this on a nightly build because the last
time I did that, it screwed up my PC :)
Assignee: firefox → xml
Component: General → XML
Product: Firefox → Core
QA Contact: general → ashshbhatt
Version: unspecified → Trunk
Through some testing of my own, I think this bug may be related to response size. I have two different popups that do very similar functions.

All JS code is located in the parent window.

The parent window pops a child window. When the user clicks on Button A, that child tells the parent to pop another child (sibling A in this case) to perform function A. Sibling A sends an email to a client, tells its older sibling to refresh its XML data, and closes itself. This function works 100% of the time.

When the user clicks Button B, the child again asks for sibling (sibling B). Sibling B charges a monetary value to the customer, tells its older sibling to refresh, and then closes itself. Although the transaction request goes through without fail, the siblings refresh FAILS 100% of the time.

Both functions are nearly identical to each other so I dug around a little bit. But adding a 1/2 second timeout to the close() function, I was able to increate sibling B's success rate to about 80%. And when it did fail, it was failing on an improperly formed XML response. That tipped me off to the fact that maybe the .close() function is aborting the XML request. Since it is being delayed, most of the time the request is completed within the 1/2 second. Othertimes it is in mid-download. Increasing the timeout to a full second increased the success rate to nearly 100%.

Going back and looking at the responses for sibling A and sibling B, the sibling B response is almost always significantly larger than the response of sibling A. So therefore, the function for sibling A rarely fails, it has less to download.

Obviously, since the codebase is all contained in the parent window, a close of a popup shouldn't abort the xmlhttprequest.

I could be mistaken however, but this is what I just discovered so I thought I would share it so that it may shed some light on this bug.
(In reply to comment #8)
update: it turns out response message size did not matter. However, if I call function B (in the above example) via a timeout of ZERO milliseconds, the request goes through 100% of the time. I discovered this by going through my code and finding that function A (in the above example) is being called by a timer as well.  Again, not sure how this will help you guys but some more info is better than nothing.
We had the same problem, we solved it using the complete url in the open call instead the relative url. It's seems that works (at least for our application) without problems.

I just experienced this bug too! You have no idea how long it has taken me to finally find out what went wrong and come up with a solution!

And that for a bug that is 3 years old and still with status NEW :S
It's really about time someone fixes it! :)
The original bug got fixed (based on the testcase) sometime between 2005-04-05 06:00 and 2005-04-10 06:00 (not sure when, because window.open was broken for a few days there).

If you're still seeing a problem, and are not the original reporter of this bug, please file a new bug on your problem, with a testcase showing it, and cc me on that bug.
Status: NEW → RESOLVED
Closed: 17 years ago
Resolution: --- → WORKSFORME
I have just encountered this bug in 2.0.0.12 (i read about it here http://www.fleegix.org/articles/2006/10/21/xmlhttprequest-and-0x80004005-ns_error_failure-error).

My problem seems to be caused by invoking xmlhttprequest via a nested event response, which basically killed xmlhttprequest for any subsequent requests.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: