为什么我收到OPTIONS请求而不是GET请求?

时间:2009-08-10 18:55:40

标签: jquery xmlhttprequest http-get http-options-method

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js" type="text/javascript"></script>
<script>
$.get("http://example.com/", function(data) {
     alert(data);
});
</script>

它对该URL执行OPTIONS请求,然后从不使用任何内容调用回调。

当它不是跨域时,它可以正常工作。

jQuery不应该只使用<script>节点进行调用,然后在加载时进行回调吗?我明白我无法得到结果(因为它是跨域的),但那没关系;我只是希望电话通过。这是一个错误,还是我做错了什么?

10 个答案:

答案 0 :(得分:235)

根据MDN

  

预检请求

     

与简单请求(如上所述)不同,首先是“预检”请求   在另一个上向资源发送HTTP OPTIONS请求标头   域,以确定实际请求是否安全   发送。跨站请求是这样的预检,因为它们可能   对用户数据有影响。特别是,请求是   预防如果:

     
      
  • 它使用GET或POST以外的方法。此外,如果使用POST发送   使用除以外的Content-Type请求数据   application / x-www-form-urlencoded,multipart / form-data或text / plain,   例如如果POST请求使用XML向服务器发送XML有效负载   application / xml或text / xml,然后请求被预检。
  •   
  • 它在请求中设置自定义标头(例如,请求使用诸如的标头   X-PINGOTHER)
  •   

答案 1 :(得分:88)

答案 2 :(得分:5)

如果您正在尝试发布

确保JSON.stringify表单数据并发送为text/plain

<form id="my-form" onSubmit="return postMyFormData();">
    <input type="text" name="name" placeholder="Your Name" required>
    <input type="email" name="email" placeholder="Your Email" required>
    <input type="submit" value="Submit My Form">
</form>
function postMyFormData() {

    var formData = $('#my-form').serializeArray();
    formData = formData.reduce(function(obj, item) {
        obj[item.name] = item.value;
        return obj;
    }, {});
    formData = JSON.stringify(formData);

    $.ajax({
        type: "POST",
        url: "https://website.com/path",
        data: formData,
        success: function() { ... },
        dataType: "text",
        contentType : "text/plain"
    });
}

答案 3 :(得分:2)

我不相信jQuery会在给出这样的URL时自然地执行JSONP请求。但是,当你告诉它使用什么参数进行回调时,它会做一个JSONP请求:

$.get("http://metaward.com/import/http://metaward.com/u/ptarjan?jsoncallback=?", function(data) {
     alert(data);
});

完全取决于接收脚本使用该参数(不必称为“jsoncallback”),因此在这种情况下,函数将永远不会被调用。但是,既然你说过你只想让metaward.com上的脚本执行,那就可以了。

答案 4 :(得分:1)

事实上,由于安全原因,不允许跨域AJAX(XMLHttp)请求(考虑从客户端获取“受限制”的网页并将其发送回服务器 - 这将是一个安全问题)

唯一的解决方法是回调。这是:创建一个新的脚本对象并将src指向端端JavaScript,这是一个带有JSON值的回调(myFunction({data}),myFunction是一个对数据执行某些操作的函数(例如,存储它)在一个变量)。

答案 5 :(得分:1)

只需更改&#34; application / json&#34; to&#34; text / plain&#34;并且不要忘记JSON.stringify(request):

var request = {Company: sapws.dbName, UserName: username, Password: userpass};
    console.log(request);
    $.ajax({
        type: "POST",
        url: this.wsUrl + "/Login",
        contentType: "text/plain",
        data: JSON.stringify(request),

        crossDomain: true,
    });

答案 6 :(得分:1)

我遇到了同样的问题。我的修复是在我的PHP脚本中添加标题,这些标题仅在开发环境中存在。

这允许跨域请求:

header("Access-Control-Allow-Origin: *");

这告诉预检请求,客户端可以发送它想要的任何标题:

header("Access-Control-Allow-Headers: *");

这样就无需修改请求。

如果您的开发人员数据库中有敏感数据可能会泄露,那么您可能会三思而后行。

答案 7 :(得分:0)

它看起来像Firefox和Opera(在Mac上测试过)不喜欢这个的跨域性(但Safari很好用)。

您可能必须调用本地服务器端代码来卷曲远程页面。

答案 8 :(得分:0)

就我而言,此问题与CORS无关,因为我向同一Web服务器发布了jQuery POST。数据为JSON,但我省略了dataType:'json'参数。

我没有(也没有添加)contentType参数,如上面David Lopes的回答所示。

答案 9 :(得分:0)

我能够在以下标题的帮助下进行修复

X < 60 == False

如果您使用的是Nodejs,则可以复制/粘贴以下代码。

Access-Control-Allow-Origin
Access-Control-Allow-Headers
Access-Control-Allow-Credentials
Access-Control-Allow-Methods