314
<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>节点进行调用,然后在加载时进行回调吗?我知道我将无法获得结果(因为它是跨域的),但没关系;我只是想让电话通过。这是一个错误,还是我做错了什么?

4

10 回答 10

286

根据MDN

预检请求

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

  • 它使用 GET 或 POST 以外的方法。此外,如果 POST 用于发送 Content-Type 不是 application/x-www-form-urlencoded、multipart/form-data 或 text/plain 的请求数据,例如,如果 POST 请求向服务器发送 XML 有效负载使用 application/xml 或 text/xml,然后预检请求。
  • 它在请求中设置自定义标头(例如,请求使用诸如 X-PINGOTHER 之类的标头)
于 2012-10-23T12:41:06.630 回答
92

选项来自http://www.w3.org/TR/cors/参见http://metajack.im/2010/01/19/crossdomain-ajax-for-xmpp-http-binding-made-easy/更多信息

于 2009-08-24T06:12:43.557 回答
9

如果您尝试发布

确保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"
    });
}
于 2017-04-05T21:58:01.613 回答
2

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

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

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

于 2009-08-10T21:14:35.200 回答
1

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

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

于 2009-08-10T19:49:19.210 回答
1

只需将“application/json”更改为“text/plain”,不要忘记 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,
    });
于 2017-09-22T16:05:51.817 回答
1

我有同样的问题。我的解决方法是向我的 PHP 脚本添加标题,这些标题仅在开发环境中存在。

这允许跨域请求:

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

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

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

这样就不需要修改请求了。

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

于 2018-02-21T19:01:24.413 回答
1

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

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

于 2018-11-12T15:52:40.987 回答
1

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

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

如果你在 Nodejs 上,这里是你可以复制/粘贴的代码。

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin','*');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  res.header('Access-Control-Allow-Credentials', true);
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH');
  next();
});
于 2019-07-17T14:43:11.187 回答
0

看起来 Firefox 和 Opera(也在 mac 上测试过)不喜欢这种跨域性(但 Safari 可以)。

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

于 2009-08-10T19:18:07.387 回答