From b73c162256fe5c7532c6d6e97453ee19e6ecac4e Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 17 Nov 2010 14:24:35 -0800 Subject: Partial fix for tickets #2194, #2393: Workaround for Meteor breaking AJAX error responses returned on posting new notices. Fixes things in Firefox 4, but Safari 5 and Chrome 8 still don't return data... either on success or failure! Sigh. The Meteor realtime plugin sets document.domain to the common prefix between the main server and the Meteor server's hostnames, which overrides the same-origin controls on JavaScript DOM access so the two parts of the app can speak to each other. This unfortunately causes "fun" side effects for XMLHTTPRequest access to the main domain... if the new domain doesn't match the actual host (eg 'status.net' instead of 'brion.status.net') then we can't access the XHR's responseXML attribute, which holds a DOM tree of the parsed XML return data. As a workaround, if we can't get at the contents there, we'll parse a fresh DOM tree in the local context from the responseText property, which remains available. In the longer term, recommend retooling the realtime stuff so it's not fiddling with document.domain. It could also be an issue as it could allow local JavaScript XSS attacks to migrate to subdomains in other open windows. --- js/util.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'js/util.js') diff --git a/js/util.js b/js/util.js index 74eef4df1..16681007a 100644 --- a/js/util.js +++ b/js/util.js @@ -236,8 +236,9 @@ var SN = { // StatusNet form.append('

Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists.

'); } else { - if ($('.'+SN.C.S.Error, xhr.responseXML).length > 0) { - form.append(document._importNode($('.'+SN.C.S.Error, xhr.responseXML)[0], true)); + var response = SN.U.GetResponseXML(xhr); + if ($('.'+SN.C.S.Error, response).length > 0) { + form.append(document._importNode($('.'+SN.C.S.Error, response)[0], true)); } else { if (parseInt(xhr.status) === 0 || jQuery.inArray(parseInt(xhr.status), SN.C.I.HTTP20x30x) >= 0) { @@ -326,6 +327,16 @@ var SN = { // StatusNet }); }, + GetResponseXML: function(xhr) { + // Work around unavailable responseXML when document.domain + // has been modified by Meteor or other tools. + try { + return xhr.responseXML; + } catch (e) { + return (new DOMParser()).parseFromString(xhr.responseText, "text/xml"); + } + }, + NoticeReply: function() { if ($('#'+SN.C.S.NoticeDataText).length > 0 && $('#content .notice_reply').length > 0) { $('#content .notice').each(function() { SN.U.NoticeReplyTo($(this)); }); -- cgit v1.2.3-54-g00ecf