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

Pau*_*jan 278 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>
Run Code Online (Sandbox Code Playgroud)

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

当它不是跨域时,它工作正常.

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

art*_*gor 249

根据MDN,

预先请求

与简单请求(如上所述)不同,"预检"请求首先将HTTP OPTIONS请求头发送到另一域上的资源,以便确定实际请求是否可安全发送.跨站点请求是这样预检的,因为它们可能对用户数据有影响.特别是,如果出现以下情况,请求会被预检:

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

  • 这解决了我们的问题,从"application/json"更改为"text/plain"停止了可怕的选项请求 (41认同)
  • @hardik请记住,通过添加CORS,您可能会接受来自任何人的请求,他们可以通过请求(POST,PUT,DELETE等)操作服务器上的数据.在这些情况下,比如在使用自定义标头时,浏览器只是首先检查服务器是否愿意在发送请求之前接受请求,因为向服务器发送未经请求的请求可能对您的数据非常危险,而且,什么是如果服务器不想接受它们,则浏览器中发送潜在大型有效负载的点,因此检查前的OPTIONS. (11认同)
  • 我不明白的是为什么浏览器请求OPTIONS方法只是为了检查实际的请求是否安全发送.但在什么意义上?我的意思是服务器也可以对某些响应标头进行限制,那么为什么需要它呢? (10认同)
  • @davidnknight如果将数据发送到服务器可能是危险的,这意味着服务器可能会受到危害,当然恶意服务器会响应您的OPTIONS请求"当然,全部发送!".那安全怎么样?(诚​​实的问题) (6认同)
  • "预检请求不是安全问题.相反,它们是一个不改变规则的东西." - 请参阅[引入预检申请背后的动机是什么]的答案(/sf/ask/1076677381/) (3认同)

Der*_*ike 7

If you're trying to POST

Make sure to JSON.stringify your form data and send as 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>
Run Code Online (Sandbox Code Playgroud)
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"
    });
}
Run Code Online (Sandbox Code Playgroud)