jquery - Chrome中的AJAX发送OPTIONS而不是GET / POST / PUT / DELETE?

我正在开发一个内部Web应用程序。 在IE10中,请求工作正常,但在Chrome中,所有AJAX请求(有很多)都是使用OPTIONS发送的,而不是我给出的任何定义的方法。 从技术上讲,我的要求是跨域。" 该站点在localhost:6120上提供,而我正在向AJAX发出请求的服务是在57124上。这个关闭的jquery错误定义了问题,但不是真正的修复。

如何在ajax请求中使用正确的http方法?

编辑:

这是在每个页面的文档加载中:

jQuery.support.cors = true;

每个AJAX都是类似的:

var url = 'http://localhost:57124/My/Rest/Call';
$.ajax({
    url: url,
    dataType: "json",
    data: json,
    async: true,
    cache: false,
    timeout: 30000,
    headers: { "x-li-format": "json", "X-UserName": userName },
    success: function (data) {
        // my success stuff
    },
    error: function (request, status, error) {
        // my error stuff
    },
    type: "POST"
});
Corey Ogburn asked 2019-08-13T08:12:26Z
9个解决方案
124 votes

Chrome正在预检查找CORS标头的请求。 如果请求是可接受的,它将发送实际请求。 如果您正在执行此跨域,则只需处理它,或者找到一种方法来使请求成为非跨域。 这就是为什么jQuery bug被关闭,因为它不会被修复。 这是设计的。

与简单的请求(如上所述)不同," preflighted" 首先要求   通过OPTIONS方法向该资源发送HTTP请求   其他域,以确定实际请求是否安全   发送。 跨站请求是这样的预检,因为它们可能   对用户数据有影响。 特别是,请求是   预检如果:

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

基于请求未在默认端口80/443上发送的事实,此Ajax调用自动被视为跨源资源(CORS)请求,换句话说,意味着请求自动发出OPTIONS请求, 检查服务器&servlet的一侧的CORS头。

即使你设置,也会发生这种情况

crossOrigin: false;

或者即使你省略它。

原因很简单就是localhost != localhost:57124。尝试仅将其发送到没有端口的localhost - 它将失败,因为请求的目标无法访问,但请注意,如果域名相等,则在没有OPTIONS请求的情况下发送请求 在POST之前。

Dropout answered 2019-08-13T08:13:50Z
3 votes

我同意Kevin B,错误报告说明了一切。 听起来你正试图进行跨域的ajax调用。 如果您不熟悉相同的原始政策,可以从这里开始:[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Same_origin_policy_for_JavaScript。]

如果这不是一个跨域的ajax调用,请尝试使您的目标URL相对,并查看问题是否消失。 如果你真的绝望地看着JSONP,但要注意,混乱潜伏着。 我们无法帮助您做更多事情。

jgitter answered 2019-08-13T08:14:26Z
1 votes

如果可以通过常规GET / POST以不同的名称传递params,并让服务器端代码处理它。

我有一个与我自己的代理相似的问题绕过CORS,我在Chrome中遇到了与POST-> OPTION相同的错误。 在我的情况下是Authorization标题(在你的情况下是"x-li-format""X-UserName"。)我最终以虚拟格式传递它(例如GET中的AuthorizatinJack)并且我更改了代理的代码以在制作时将其转换为标题 打电话到目的地。 这是PHP:

if (isset($_GET['AuthorizationJack'])) {
    $request_headers[] = "Authorization: Basic ".$_GET['AuthorizationJack'];
}
Aidin answered 2019-08-13T08:15:02Z
1 votes

就我而言,我正在调用AWS(API网关)托管的API。 当我尝试从API自己的域以外的域调用API时发生错误。 由于我是API所有者,因此我为测试环境启用了CORS,如Amazon文档中所述。

在生产中,此错误不会发生,因为请求和api将在同一个域中。

我希望它有所帮助!

gbonesso answered 2019-08-13T08:15:44Z
0 votes

正如@Dark Falcon所回答,我只是处理它。

在我的例子中,我使用node.js服务器,并创建一个不存在的会话。 由于OPTIONS方法中没有会话详细信息,因此最终为每个POST方法请求创建一个新会话。

所以在我的app例程中创建会话 - 如果不存在,我只是添加了一个检查以查看方法是否为OPTIONS,如果是,则跳过会话创建部分:

    app.use(function(req, res, next) {
        if (req.method !== "OPTIONS") {
            if (req.session && req.session.id) {
                 // Session exists
                 next();
            }else{
                 // Create session
                 next();
          }
        } else {
           // If request method is OPTIONS, just skip this part and move to the next method.
           next(); 
        }
    }
Mahesh answered 2019-08-13T08:16:25Z
0 votes

"预检" 请求首先通过OPTIONS方法向另一个域上的资源发送HTTP请求,以确定实际请求是否可以安全发送。 跨站请求

[https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS]

Noorullah answered 2019-08-13T08:16:58Z
0 votes

考虑使用axios

axios.get( url,
{ headers: {"Content-Type": "application/json"} } ).then( res => {

  if(res.data.error) {

  } else { 
    doAnything( res.data )
  }

}).catch(function (error) {
   doAnythingError(error)
});

我有这个问题使用fetch和axios完美地工作。

Evhz answered 2019-08-13T08:17:30Z
0 votes

我遇到了一个非常类似的问题。 我花了将近半天的时间来理解为什么一切都在Firefox中正常运行并且在Chrome中失败。 在我的情况下,这是因为我的请求标头中的重复(或可能是错误的)字段。

Andrew Tatomyr answered 2019-08-13T08:17:56Z
translate from https://stackoverflow.com:/questions/21783079/ajax-in-chrome-sending-options-instead-of-get-post-put-delete