Javascript 跨域 XHR 失败

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13464921/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 12:09:45  来源:igfitidea点击:

Cross domain XHR failing

javascriptbackbone.jsxmlhttprequestcors

提问by xbonez

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

我在一个域上托管了一个 API,该域启用了以下标头的 CORS:

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.com and it works fine. Link: http://hackst.com/#w3SbV

我可以从 hackst.com 发出 GET 或 POST 请求,并且工作正常。链接:http: //hackst.com/#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:

从我托管在另一个域上的主干应用程序中,GET 请求工作正常。但是当我尝试创建并保存新模型(即发出 POST 请求)时,它失败并显示以下错误:

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 createmethod and making a POST request manually like this:

我什至尝试覆盖该create方法并像这样手动发出 POST 请求:

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

    $.ajax({
        "url" : this.url,
        "async" : true,
        "beforeSend" : function(obj){
            console.log(obj);
        },
        "contentType" : 'application/json',
        //"crossDomain" : true,  // uncommenting 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.net/X9cqh/5/), but that fails even though my backbone app can make the GET request fine.

我也在 JSFiddle 上尝试了一个独立的 GET 请求(http://jsfiddle.net/X9cqh/5/),但即使我的主干应用程序可以使 GET 请求正常,但还是失败了。

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

在这一点上,我完全一无所知。任何提示,指针,解决方案?

采纳答案by monsur

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.org/TR/cors/).

这是必要的,因为内容类型是 application/json,它超出了 CORS 规范 (http://www.w3.org/TR/cors/) 中定义的可接受值。

回答by kybernetikos

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

添加“Content-Type”标头使您的 CORS 请求失败的原因是您的服务器设置错误。

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.

如果客户端希望指定特定的标头或使用不寻常的 http 方法动词(例如 PUT),那么浏览器将首先执行“预检”OPTIONS 调用以确保允许设置这些标头。您的服务器需要使用适当的标头响应此 OPTIONS 调用。如果您想确认这是问题所在,您将在 Chrome 开发人员工具或 firebug 的网络选项卡中看到该选项调用。

You may be interested in my more detailed answer here.

你可能对我这里更详细的回答感兴趣。

回答by teddybeard

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:

您的服务器设置有效。JSFiddle 显然不会发出 ajax 请求,但是您可以通过在 Chrome 控制台或 Safari 开发者控制台中输入以下四行来快速测试它是否有效:

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

enter image description here

在此处输入图片说明

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

如果您使用不允许 CORS 的域尝试此操作,则会出错。