3

私は週末中ずっとこれに苦労してきました。この問題は、Mac コンピューターを介してアクセスし、nodejitsu インスタンスを介してホストされている場合にのみ発生し、localhost サーバーには存在しません。

私のアプリケーションは非常に典型的です。別のドメインに 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 ターミナルで pre-preflight という次のエラーが表示されます。

    オプション 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 では非常によく似ています:

    「NetworkError: 502 Bad Gateway - http://api.dev.XXXX.com/users/fbauth」
    fbauth
    Cross-Origin Request Blocked: Same Origin Policy により、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/cvince/6nPLJ/

問題 -- メインの開発マシンでは失敗しますが、うまくいっているかもしれません。要求は、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 に答える