Skip to main content

Bug Tracker

Side navigation

#8318 closed bug (invalid)

Opened February 18, 2011 03:47PM UTC

Closed February 19, 2011 06:06PM UTC

Last modified April 18, 2011 03:45PM UTC

Incorrect headers are sent when performing cross-domain ajax request

Reported by: anonymous Owned by: anonymous
Priority: low Milestone: 1.next
Component: ajax Version: 1.5
Keywords: Cc:
Blocked by: Blocking:
Description

When I perform cross-domain ajax request:

$.ajax({
    url:'http://fbtest/cross.php',
    crossDomain:true,
    data:{
        a:5
    },
    type:'POST',
    dataType:'json',
    success:function(data, textStatus, jqXHR) {
        alert(data.name);
    }
});

Script that sends response is:

<?php
header('Access-Control-Allow-Origin: *');
echo file_get_contents('cross.json');

cross.json is:

{
    "name": "konst"
}

When I do GET request, everything is fine. When I do POST, request is not sent and in chrome it says:

XMLHttpRequest cannot load http://fbtest/cross.php. Request header field x-requested-with is not allowed by Access-Control-Allow-Headers.

I've tracked down the code and found these lines in development version of jquery 1.5:

// Requested-With header
// Not set for crossDomain requests with no content
// (see why at http://trac.dojotoolkit.org/ticket/9486)
// Won't change header if already provided
if ( !( s.crossDomain && !s.hasContent ) && !headers["x-requested-with"] ) {
	headers[ "x-requested-with" ] = "XMLHttpRequest";
}

So you've got it right - you should NOT set x-requested-with header for cross-domain request. However you do. When I comment out this logic, it works fine. I think there is something wrong with checks you do.

Attachments (0)
Change History (9)

Changed February 18, 2011 05:12PM UTC by jitter comment:1

component: unfiledajax
description: When I perform cross-domain ajax request: \ $.ajax({ \ url:'http://fbtest/cross.php', \ crossDomain:true, \ data:{ \ a:5 \ }, \ type:'POST', \ dataType:'json', \ success:function(data, textStatus, jqXHR) { \ alert(data.name); \ } \ }); \ Script that sends response is: \ <?php \ header('Access-Control-Allow-Origin: *'); \ echo file_get_contents('cross.json'); \ \ cross.json is: \ { \ "name": "konst" \ } \ \ When I do GET request, everything is fine. When I do POST, request is not sent and in chrome it says: \ XMLHttpRequest cannot load http://fbtest/cross.php. Request header field x-requested-with is not allowed by Access-Control-Allow-Headers. \ \ I've tracked down the code and found these lines in development version of jquery 1.5: \ // Requested-With header \ // Not set for crossDomain requests with no content \ // (see why at http://trac.dojotoolkit.org/ticket/9486) \ // Won't change header if already provided \ if ( !( s.crossDomain && !s.hasContent ) && !headers["x-requested-with"] ) { \ headers[ "x-requested-with" ] = "XMLHttpRequest"; \ } \ \ So you've got it right - you should NOT set x-requested-with header for cross-domain request. However you do. When I comment out this logic, it works fine. I think there is something wrong with checks you do.When I perform cross-domain ajax request: \ {{{ \ $.ajax({ \ url:'http://fbtest/cross.php', \ crossDomain:true, \ data:{ \ a:5 \ }, \ type:'POST', \ dataType:'json', \ success:function(data, textStatus, jqXHR) { \ alert(data.name); \ } \ }); \ }}} \ Script that sends response is: \ {{{ \ <?php \ header('Access-Control-Allow-Origin: *'); \ echo file_get_contents('cross.json'); \ }}} \ cross.json is: \ {{{ \ { \ "name": "konst" \ } \ }}} \ When I do GET request, everything is fine. When I do POST, request is not sent and in chrome it says: \ {{{ \ XMLHttpRequest cannot load http://fbtest/cross.php. Request header field x-requested-with is not allowed by Access-Control-Allow-Headers. \ }}} \ \ I've tracked down the code and found these lines in development version of jquery 1.5: \ {{{ \ // Requested-With header \ // Not set for crossDomain requests with no content \ // (see why at http://trac.dojotoolkit.org/ticket/9486) \ // Won't change header if already provided \ if ( !( s.crossDomain && !s.hasContent ) && !headers["x-requested-with"] ) { \ headers[ "x-requested-with" ] = "XMLHttpRequest"; \ } \ }}} \ So you've got it right - you should NOT set x-requested-with header for cross-domain request. However you do. When I comment out this logic, it works fine. I think there is something wrong with checks you do.
priority: undecidedlow

Changed February 18, 2011 05:30PM UTC by jaubourg comment:2

Requests with a body will issue a preflight request. Your script doesn't set Access-Control-Allow-Headers for the preflight request. So "you've got it right" - you SHOULD set Access-Control-Allow-Headers properly during the preflight request: http://www.w3.org/TR/cors/#access-control-allow-headers-response-he

X-Requested-With is important for services that want to allow/disallow specific requesters and you should be using Access-Control-Allow-Headers since you'll need it whenever you have to pass custom headers.

Changed February 18, 2011 07:10PM UTC by jitter comment:3

owner: → anonymous
status: newpending

Changed February 19, 2011 04:19PM UTC by anonymous comment:4

status: pendingnew

Google took me here ... jauborg: Can you specify HOW you'd "set Access-Control-Allow-Headers properly during the preflight request" ? I've tried a number of header combinations in my serverside PHP script, and still can't get things working properly. What's the correct way of doing this type of request? We're not the only ones with this problem it seems:

http://forum.jquery.com/topic/jquery-1-5-latest-chrome-post-ajax-request-xmlhttprequest-cannot-load-url-request-header-field-x-requested-with-is-not-allowed-by-access-control-allow-headers

Changed February 19, 2011 04:27PM UTC by anonymous comment:5

Ok, got it ... You need to add <?php header("Access-Control-Allow-Headers: x-requested-with"); ?>

To your serverside script. Sorry about my whinging ;)

Changed February 19, 2011 06:06PM UTC by snover comment:6

resolution: → invalid
status: newclosed

Changed April 15, 2011 03:49PM UTC by matas comment:7

I'm sorry to intervene, but no way this ticket is closed/invalid:

The jxhr should never set any X- header for the crossDomain requests, it says it in the script comment too:

if ( !s.crossDomain && !headers["X-Requested-With"] ) {

headers[ "X-Requested-With" ] = "XMLHttpRequest";

}

the bug is somewhere in the setting of the crossDomain when it's a 'post' request. it could also have implications in other code areas where the s.crossDomain property is evaluated.

here's another test script:

http://jsfiddle.net/RjVVg/

please change it back to open!

Changed April 18, 2011 03:29PM UTC by Agos comment:8

I'll second the request for reopening. A server-side workaround is not enough, think of third-party APIs.

Changed April 18, 2011 03:45PM UTC by Agos comment:9

Whoops sorry, seems like jQuery 1.5.2 fixes this.