Javascript 为什么HTTP服务器会将通过AJAX发送帖子解释为选项,而通过CURL发送帖子则实际上是一个PUT? 我正在测试我用C++和Boost库开发的HTTP服务器。更具体地说,我正在测试一个端点,其中PUT接收JSON

Javascript 为什么HTTP服务器会将通过AJAX发送帖子解释为选项,而通过CURL发送帖子则实际上是一个PUT? 我正在测试我用C++和Boost库开发的HTTP服务器。更具体地说,我正在测试一个端点,其中PUT接收JSON,javascript,json,ajax,http,Javascript,Json,Ajax,Http,为了测试RESTFul Web服务,我使用Curl和以下命令: curl-H“Content Type:application/json”-H“Content Length:34”-H“Connection:close”-X PUT--data“@response\u json” 其中response_json是一个包含要发送的json的文件。这很好,服务器接收请求作为PUT,并执行应该执行的操作 但是,当我使用以下方法从AJAX测试Web服务时: function sendPut2() {

为了测试RESTFul Web服务,我使用Curl和以下命令:

curl-H“Content Type:application/json”-H“Content Length:34”-H“Connection:close”-X PUT--data“@response\u json”

其中response_json是一个包含要发送的json的文件。这很好,服务器接收请求作为PUT,并执行应该执行的操作

但是,当我使用以下方法从AJAX测试Web服务时:

function sendPut2() {
    var http = new XMLHttpRequest();
    var url = 'http://localhost:8080/answer';
    var data = JSON.stringify({"question": "a", "answer": "b"});
    http.open("PUT", url, true);
    http.setRequestHeader("Content-type", "application/json");
    http.setRequestHeader("Content-Length", data.length);
    http.setRequestHeader("Connection", "close");
    http.onreadystatechange = function() { 
        if(http.readyState == 4 && http.status == 200) {
            alert(http.responseText);
        }
    }
    http.send(data);
}
服务器将其作为选项接收,但不工作。此外,在Firebug控制台中,我可以看到:“NetworkError:404未找到-”

我试过Firefox和Chrome。我的javascript代码有什么问题

这是带有Javascript请求的Firebug:


出于安全原因,浏览器具有相同的源策略。当您从与当前网页加载来源不同的来源请求浏览器中的Ajax时,则该请求受同一来源策略的约束。目标站点可以选择支持CORS(跨源资源共享),这是浏览器实现的一种特定方案,允许其询问目标站点特定跨源请求是否正常

在卖出请求之前使用期权请求是CORS方案的一部分。如果浏览器检测到原始跨源请求的某些条件,则它将首先发出一个选项请求,如果从中得到正确的响应,则它将发出目标请求(在您的案例中为PUT)。可以触发浏览器使用选项请求的内容包括自定义标题、所需的特定授权类型、特定内容类型、特定请求类型等

另一方面,CURL不强制执行这种同源安全性(这是一种为自己的网页安全模型而发明的浏览器),因此它只直接发送PUT请求,而不需要先从OPTIONS请求获得正确的答案


仅供参考,如果浏览器中发出Ajax请求的Javascript与加载的包含Javascript的网页来自同一来源,则不应触发选项请求,因为这将是同一来源请求,而不是跨来源请求。如果您有本地服务器,请确保网页也从本地服务器(相同的主机名和端口号)加载,而不是从文件系统加载,也不是从一个使用IP地址的服务器加载,另一个使用localhost或类似的东西加载。就浏览器而言,主机名必须在物理上相同,而不仅仅是相同的IP地址


以下是关于使用选项请求“预引导”的请求的信息:

预检请求

与上面讨论的简单请求不同,“预飞行”请求优先 通过OPTIONS方法向上的资源发送HTTP请求 其他域,以确定实际请求是否安全 发送。跨站点请求是这样预处理的,因为它们可能 对用户数据有影响。特别是,请求是 如果:

它使用的方法不是GET、HEAD或POST。此外,如果使用POST 发送内容类型不是的请求数据 application/x-www-form-urlencoded、多部分/表单数据或text/plain, e、 g.如果POST请求使用 application/xml或text/xml,则请求被预引导。它设定 请求中的自定义标头(例如,请求使用诸如 X射线(其他)


仅供参考,以下是CORS各方面的详细信息。因为您的请求是看跌期权,所以它将出现在该文章的“不那么简单的请求”部分。

确保您的请求来源相同,如果不是,则有两种选择。1.服务器必须使用access control allow Originates标头进行响应。2.暂时安装chrome cors插件chrome cors插件并不能真正解决选项问题。在某些情况下,您最好使用chrome的
--disable web security
命令行选项进行测试。