3

整个周末我一直在努力解决这个问题。该问题仅在通过 mac 计算机访问并通过我的 nodejitsu 实例托管时存在,并且在我的本地主机服务器上不存在。

我的申请很典型。它在不同的域上有一个 Web 服务器组件和 REST 服务器——因此需要 CORS。唯一增加的复杂性是自定义标题。

我已经在我的 node.js 服务器上设置了 CORS,如下所示

var allowCrossDomain = function(req, res, next) {

    console.log(req.headers);

    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Accept, X-api-key, X-auth-token, Content-Type, Content-Length');

    // intercept OPTIONS method
    if ('OPTIONS' == req.method) {
        res.header('Access-Control-Allow-Origin', '*');
        res.header('Access-Control-Allow-Headers', 'Accept, X-api-key, X-auth-token, Content-Type, Content-Length');
        res.send(200, {});
    }
    else {
      next();
    }
};

前端 $.ajax 调用是这样的

//create user
$.ajax({
    url: host + 'users',
    headers: {'X-api-key': apikey},
    type: 'POST',
    dataType: 'json',
    contentType: 'application/json',
    data: JSON.stringify({
        email: userInfo.email,
        username: username,
        password: pasword,
    }),
    xhrFields: {},
    crossDomain: true,
    success: function (res) {
        console.log(res);
        $('.messages')
            .removeClass('error')
            .addClass('success')
            .html('<strong>Success! </strong>Check email for activation link');
    },
    error: function (xhr, status, errorThrown) {
        console.log(xhr.responseText);
        var errorMessage = $.parseJSON(xhr.responseText);
        $('.messages')
            .removeClass('success')
            .addClass('error')
            .html('<strong>Oops!</strong> '+errorMessage.error);

    }
});

从技术上讲,这应该可行。这是对节点服务器的教科书 ajax 调用,但是当我在 chrome 中进行调用时,我在 chrome 终端中预检时收到以下错误。

    选项 http://api.dev.XXXXX.com/users/login net::ERR_EMPTY_RESPONSE
    jquery-1.7.2.js:8240
    发送 jquery-1.7.2.js:8240
    jQuery.extend.ajax jquery-1.7.2.js:7719
    (匿名函数)VM62:2
    InjectedScript._evaluateOn VM57:730
    InjectedScript._evaluateAndWrap VM57:669
    InjectedScript.evaluate

在 firefox/mozilla 上是这样,在 Safari 上它非常相似:

    “网络错误:502 错误网关 - http://api.dev.XXXX.com/users/fbauth”
    fbauth
    跨域请求被阻止:同源策略不允许在 http://api.dev.XXXX.com/users/fbauth 读取远程资源。这可以通过将资源移动到同一域或启用 CORS 来解决。

我通过在复杂的 HTTP 请求之前向服务器发送简单的 HTTP 请求,以某种方式设法部分绕过了这一点。我不知道为什么这使它起作用,这使它成为世界上最丑陋、最有效的黑客。

  $(document).ready(function(){
    setTimeout(function(){
    $.ajax({
      url: host + 'users/login',
      type: 'POST',
      dataType: 'json',
      data: JSON.stringify({

      })
    });

    $.ajax({
      url: host + 'users/fbauth',
      type: 'POST',
      dataType: 'json',
      data: JSON.stringify({

      })
    });

    }, 500);
  })

现在的问题是,在执行简单的 HTTP 后几乎必须立即执行预检,因此,使用 fb 登录的 oauth 不起作用,因为它在执行需要执行的操作之前对 fb 执行了一些请求并返回。

我完全被困在这里。这是 webkit/mozilla 引擎问题吗?还是我在这里遗漏了一些关键的东西?

这是一个带有对测试端点的示例请求的 jsfiddle。运行时检查控制台。 http://jsfiddle.net/cvnce/6nPLJ/

ISSUE-- 在我的主要开发机器上失败,但它可能对你有用。该请求在我的 6 台计算机中的 4 台上进行了预检和正确验证。

4

1 回答 1

3

原来是我的VPN客户端引起的。边缘案例!这是解决方案: http ://www.bennadel.com/blog/2559-cisco-anyconnect-vpn-client-may-block-cors-ajax-options-requests.htm

于 2014-06-30T23:31:00.840 回答