Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

FF 3.5 Cross Domain XMLHttpRequest Problem

27 views
Skip to first unread message

kjh21

unread,
Jul 3, 2009, 8:06:33 PM7/3/09
to
I have an AJAX application running under FireFox that makes Cross-
Domain XMLHttpRequests. Prior to FireFox 3.5, I was using the
netscape.security.PrivilegeManager to enable the appropriate
privilege.

I was pleased to learn that FF 3.5 supports the W3C's proposed
Access Control for Cross-Site Requests which provides
a way for web servers to support cross-site access controls that
enable secure cross-site data transfers. Of particular note is that
FF 3.5 claims support for this capabilitiy with XMLHttpRequest (see
https://developer.mozilla.org/en/HTTP_access_control)

I'm having a problem though getting working in accordance with the
standard the following code which which uses XMLHttpRequest to
generate an HTTP POST.

var xhr = new XMLHttpRequest( );

var someURL = "http://some-domain-here.com/
some_resource_here.html";
var params = "parameter=value goes here.";
xhr.open("POST", someURL, true);

xhr.setRequestHeader("Content-type", "application/x-www-
form-urlencoded");
xhr.setRequestHeader("Content-length", params.length);
xhr.setRequestHeader("Connection", "close");

xhr.onerror = errorHandler;
xhr.onreadystatechange =
function() {
if(xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
};

xhr.send(params);

function errorHandler( e ) {
alert( "Error processing XMLHttpRequest: " +
e.target.status );
}

My experience contradicts the documentation in that this code leads to
a
"preflighted" request that first sends an HTTP OPTIONS request header
to the resource on the other domain, in order to determine whether the
actual request is safe to send. The documentation states

=============================================================
In particular, a request is preflighted if:

* It uses methods other than GET or POST. Also, if POST is used to
send request data with a Content-Type other than application/x-www-
form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST
request sends an XML payload to the server using application/xml or
text/xml, then the request is preflighted.

* It sets custom headers in the request (e.g. the request uses a
header such as X-PINGOTHER)

==============================================================

My POST uses Content-Type: application/x-www-form-urlencoded
and is not setting any custom headers.

Why the preflighted request?

Any help would be appreciated.

kjh21

unread,
Jul 6, 2009, 12:15:11 PM7/6/09
to
On Jul 3, 8:06 pm, kjh21 <kheal...@gmail.com> wrote:
> I have an AJAX application running under FireFox that makesCross-DomainXMLHttpRequests.  Prior to FireFox 3.5, I was using the

> netscape.security.PrivilegeManager to enable the appropriate
> privilege.
>
> I was pleased to learn that FF 3.5 supports the W3C's  proposed
> Access Control forCross-Site Requests which provides

> a way for web servers to supportcross-site access controls that
> enable securecross-site data transfers.  Of particular note is that
> FF 3.5 claims support for this capabilitiy with XMLHttpRequest (seehttps://developer.mozilla.org/en/HTTP_access_control)

>
> I'm having a problem though getting working in accordance with the
> standard the following code which which uses XMLHttpRequest to
> generate an HTTP POST.
>
>           var xhr = new XMLHttpRequest( );
>
>           var someURL = "http://some-domain-here.com/
> some_resource_here.html";
>           var params = "parameter=value goes here.";
>           xhr.open("POST", someURL, true);
>
>           xhr.setRequestHeader("Content-type",   "application/x-www-
> form-urlencoded");
>           xhr.setRequestHeader("Content-length", params.length);
>           xhr.setRequestHeader("Connection",     "close");
>
>           xhr.onerror = errorHandler;
>           xhr.onreadystatechange =
>              function() {
>                if(xhr.readyState == 4 && xhr.status == 200) {
>                    alert(xhr.responseText);
>                }
>              };
>
>           xhr.send(params);
>
>           function errorHandler( e ) {
>              alert( "Error processing XMLHttpRequest:  " +
> e.target.status );
>           }
>
> My experience contradicts the documentation in that this code leads to
> a
> "preflighted" request that first sends an HTTP OPTIONS request header
> to the resource on the otherdomain, in order to determine whether the

> actual request is safe to send.   The documentation states
>
> =============================================================
>  In particular, a request is preflighted if:
>
> * It uses methods other than GET or POST.  Also, if POST is used to
> send request data with a Content-Type other than application/x-www-
> form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST
> request sends an XML payload to the server using application/xml or
> text/xml, then the request is preflighted.
>
> * It sets custom headers in the request (e.g. the request uses a
> header such as X-PINGOTHER)
>
> ==============================================================
>
> My POST uses Content-Type:  application/x-www-form-urlencoded
> and is not setting any custom headers.
>
> Why the preflighted request?
>
> Any help would be appreciated.

I exhausted my options trying things with my client code to determine
why this is not working in accordance with the W3C's recommended
Access Control for Cross-Site Requests standard (see http://www.w3.org/TR/access-control/
for the proposed standard and https://developer.mozilla.org/en/HTTP_access_control
for Mozilla's explanation of their implementation).

Instead, I took a look at Mozilla's source code implementation of the
XMLHttpRequest in FF 3.5 and found the following in
nsXMLHttpRequest.cpp

=======================================================
nsresult
nsXMLHttpRequest::CheckChannelForCrossSiteRequest(nsIChannel*
aChannel)
{
nsresult rv;

// First check if this is a same-origin request, or if cross-site
requests
// are enabled.
if ((mState & XML_HTTP_REQUEST_XSITEENABLED) ||
CheckMayLoad(mPrincipal, aChannel)) {
return NS_OK;
}

// This is a cross-site request
mState |= XML_HTTP_REQUEST_USE_XSITE_AC;

// Check if we need to do a preflight request.
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
NS_ENSURE_TRUE(httpChannel, NS_ERROR_DOM_BAD_URI);

nsCAutoString method;
httpChannel->GetRequestMethod(method);
if (!mACUnsafeHeaders.IsEmpty() ||
HasListenersFor(NS_LITERAL_STRING(UPLOADPROGRESS_STR)) ||
(mUpload && mUpload->HasListeners())) {
mState |= XML_HTTP_REQUEST_NEED_AC_PREFLIGHT;
}
else if (method.LowerCaseEqualsLiteral("post")) {
nsCAutoString contentTypeHeader;
httpChannel->GetRequestHeader(NS_LITERAL_CSTRING("Content-Type"),
contentTypeHeader);

nsCAutoString contentType, charset;
rv = NS_ParseContentType(contentTypeHeader, contentType, charset);
NS_ENSURE_SUCCESS(rv, rv);

if (!contentType.LowerCaseEqualsLiteral("text/plain")) {
mState |= XML_HTTP_REQUEST_NEED_AC_PREFLIGHT;
}
}
else if (!method.LowerCaseEqualsLiteral("get") &&
!method.LowerCaseEqualsLiteral("head")) {
mState |= XML_HTTP_REQUEST_NEED_AC_PREFLIGHT;
}

return NS_OK;
}
========================================================

Looks to me like HTTP POSTs with anything other than a Content-Type of
"text/plain" get preflighted. That overlooks "application/x-www-form-
urlencoded" and "multipart/form-data" which, according to the proposed
standard, should not require "preflighting".

I changed my Content-Type to "plain/text" and the Cross Domain request
made it through without preflighting but the (Java-based) server side
code that processes the request fails because it is expecting, in
general, a posting of HTML FORM data with an associated Content-Type
of "application/x-www-form-urlencoded".

Can someone in the development group confirm this and, if necessary,
log a bug report?


Kevin H.


Nikhil

unread,
Jul 7, 2009, 2:25:21 AM7/7/09
to
> Access Control for Cross-Site Requests standard (seehttp://www.w3.org/TR/access-control/
> for the proposed standard andhttps://developer.mozilla.org/en/HTTP_access_control

I am not from the development group, but having the same problem, a
request is NOT preflighted only if it is "text/plain". However, my
requirement is a non-preflighted request with Content-Type of
"application/x-www-form-urlencoded", trying to find a workaround for
this one.

Thiago Oliveira

unread,
Jul 14, 2009, 7:10:03 PM7/14/09
to

I'm experiencing this exact same thing. A request is NOT preflighted


only if it is "text/plain". However, my requirement is a non-
preflighted request with Content-Type of "application/x-www-form-

urlencoded". Has anyone found a workaround to this yet?

0 new messages