最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Cross domain XHR failing - Stack Overflow

programmeradmin2浏览0评论

I have an API hosted on one domain that has CORS enabled with the following headers:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Max-Age: 1728000

I am able to make a GET or POST request from hackst and it works fine. Link:

From my backbone app hosted on another domain, GET requests work fine. But when I try to create and save a new model (i.e. make a POST request), it fails with the following error:

Failed to load resource: the server responded with a status of 501 (Not Implemented) :5000/api/posts
XMLHttpRequest cannot load :5000/api/posts. Origin  is not allowed by Access-Control-Allow-Origin.

My relevant backbone code:

var newPostData = {
    topic : "New Post",
    body : "new body",          
    user_id : 1,
};  

var newPostModel = new Post(newPostData);
this.model.create(newPostModel);

I even tried over-riding the create method and making a POST request manually like this:

create : function(data) {
    console.log('overriden create');

    $.ajax({
        "url" : this.url,
        "async" : true,
        "beforeSend" : function(obj){
            console.log(obj);
        },
        "contentType" : 'application/json',
        //"crossDomain" : true,  // unmenting this doesnt help either
        "headers" : {

        },
        "dataType" : 'json',
        "type" : 'POST',
        "data" : JSON.stringify(data),
        "error" : function(err){
            console.log('new post creation failed');
            console.log(err);
        },
        "success" : function(resp){
            console.log('new post created');
            console.log(resp);
        }
    });
}

Same error.

I tried a stand-alone GET request on JSFiddle as well (/), but that fails even though my backbone app can make the GET request fine.

I'm pletely clueless at this point. Any hints, pointers, solutions?

I have an API hosted on one domain that has CORS enabled with the following headers:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Max-Age: 1728000

I am able to make a GET or POST request from hackst. and it works fine. Link: http://hackst./#w3SbV

From my backbone app hosted on another domain, GET requests work fine. But when I try to create and save a new model (i.e. make a POST request), it fails with the following error:

Failed to load resource: the server responded with a status of 501 (Not Implemented) http://projectwhatup.us:5000/api/posts
XMLHttpRequest cannot load http://projectwhatup.us:5000/api/posts. Origin http://ayush.projectwhatup.us is not allowed by Access-Control-Allow-Origin.

My relevant backbone code:

var newPostData = {
    topic : "New Post",
    body : "new body",          
    user_id : 1,
};  

var newPostModel = new Post(newPostData);
this.model.create(newPostModel);

I even tried over-riding the create method and making a POST request manually like this:

create : function(data) {
    console.log('overriden create');

    $.ajax({
        "url" : this.url,
        "async" : true,
        "beforeSend" : function(obj){
            console.log(obj);
        },
        "contentType" : 'application/json',
        //"crossDomain" : true,  // unmenting this doesnt help either
        "headers" : {

        },
        "dataType" : 'json',
        "type" : 'POST',
        "data" : JSON.stringify(data),
        "error" : function(err){
            console.log('new post creation failed');
            console.log(err);
        },
        "success" : function(resp){
            console.log('new post created');
            console.log(resp);
        }
    });
}

Same error.

I tried a stand-alone GET request on JSFiddle as well (http://jsfiddle/X9cqh/5/), but that fails even though my backbone app can make the GET request fine.

I'm pletely clueless at this point. Any hints, pointers, solutions?

Share Improve this question asked Nov 20, 2012 at 0:39 AyushAyush 42.5k51 gold badges167 silver badges241 bronze badges 6
  • looking at hurl.it HEAD request to your server, it looks like CORS is only enabled for http://ayush.projectwhatup.us – teddybeard Commented Nov 20, 2012 at 1:02
  • How e the request from hackst. goes through, though? – Ayush Commented Nov 20, 2012 at 1:09
  • It's because the request is not being made by your web browser. Similar to Hurl.it, when you create a hackst. request, it is executed by their server on the back end and then displays the results in your web browser. – teddybeard Commented Nov 20, 2012 at 1:12
  • CORS enables one webpage to access information on another domain directly inside the browser, for example an ajax request. Outside the browser, anybody can make HTTP requests to any server at any time. For example, you can telnet 80 into projectwhatup.us right now from any puter regardless if they have CORS enabled. – teddybeard Commented Nov 20, 2012 at 1:16
  • Ah! I hadn't thought of the fact that hurl and hackst were making the request via the back-end. – Ayush Commented Nov 20, 2012 at 1:37
 |  Show 1 more ment

3 Answers 3

Reset to default 6

The server should also reply to the preflight with the following header:

Access-Control-Allow-Headers: Content-Type

This is necessary because the content type is application/json, which is outside the acceptable values defined in the CORS spec (http://www.w3/TR/cors/).

Your sever setup works. JSFiddle apparently does not make the ajax requests, but you can quickly test that it works by entering these four lines into Chrome console or Safari developer console:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://projectwhatup.us:5000/api/posts', false);
xhr.send();
xhr.responseText;

If you try this with a domain that does not allow CORS, it will error out.

The reason that adding a 'Content-Type' header makes your CORS request fail is because your server is set up wrongly.

If the client wishes to specify particular headers or use an unusual http method verb (e.g. PUT), then the browser will first do a 'preflight' OPTIONS call to ensure that it is allowed to set those headers. Your server needs to respond to this OPTIONS call with the appropriate headers. You'll see that options call in the network tab of the Chrome developer tools or firebug if you want to confirm that this is what the problem is.

You may be interested in my more detailed answer here.

发布评论

评论列表(0)

  1. 暂无评论