6

これは私を夢中にさせています。

jQuery 1.4.2、Windows XP SP3

これが私のテストです。

Firefox 3.5+ を読み込む

http://plungjan.name/test/testcors.html

作品

ファイルをハードディスクに保存し、そこから実行します

私のオフィスからは、外部は機能し、内部は機能しません

また興味深いのは、一度に両方を実行できないことです。

背景: CORSを使用する内部 Web サービスにGETを実行します。こちらこちらで詳しく説明されているように、v3.5 以降では FF がクロス ドメイン リクエストを処理しないという回答を投稿しないでください。

IE8 および FF3.6.6 では、1 つのサーバーから別のサーバーへ、そして現在はほぼファイル システム (file:///) からサービスへと動作します。 ファイル システムからのみ、FF 3.6.6 がネゴシエートする必要がある場合 (ユーザーは既にログインし、承認されており、資格情報を送信しています!)ネゴシエーション後にデータを取得できません。jQuery xhrはステータス0を返し、data/responseTextなどはありません私には思えますが、jQueryは反応し、200からではなく401からxhrを保存しますOK後で

XHR オブジェクトにアラートを送信したときに、通信の最後に得られる結果は次のとおりです。

Status:success 
Data:[] 
XHR: 
some native functions,
readyState:4 
status:0
responseXML:null 
responseText: 
withCredentials:true

同じサーバーに呼び出しを行うが資格情報を必要としない場合、データはクロスドメインで問題なく返されます

したがって、通信は次のようになります。

GET /restapplicationusingcors/authenticationneeded-internal/someid
Accept: application/json
Accept-Language: en
.
.
Origin: null
Cookie: LtpaToken=...

リターンは

HTTP/1.1 401 Unauthorized
Server: Apache
Pragma: No-cache
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 01:00:00 CET
WWW-Authenticate: Negotiate
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html

その後、FF が送信されます

GET /restapplicationusingcors/authenticationneeded-internal/someid HTTP/1.1
Host: myhost.myintranet.bla
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6
Accept: application/json
Accept-Language: en
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Origin: null
Cookie: LtpaToken=....
Authorization: Negotiate ....

必要なファイルが与えられますが、FF で取得できません:

HTTP/1.1 200 OK
Date: Tue, 20 Jul 2010 12:08:39 GMT
Pragma: No-cache
Cache-Control: no-cache, max-age=600, s-maxage=3600
Expires: Thu, 01 Jan 1970 01:00:00 CET
X-Powered-By: ...
Content-Disposition: inline;filename=nnnnnn.json
Content-Language: en
Access-Control-Allow-Origin: ...
Keep-Alive: timeout=6, max=70
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json;charset=UTF-8

サーバーから送信されたデータがXHR オブジェクトにありません

これが私のコードです

function getJSON(url,func,lang) {
  accept = 'application/json';
  lang=lang?lang:"*";
  // gruesome hack to handle that APPENDS the mime header to */* !!!
  // NOW HANDLED by first setting Accept to "" !!! 
//  if ($.browser.msie && url.indexOf('serveAsMime')==-1)  {
//    url+= '?serveAsMime='+accept;
//  }
  if (currentRequest != null) currentRequest.abort();
  var requestObjectJSON =   {
    url    : url,
//    dataType: "json",
    method : 'get',
    beforeSend: function(xhr){
      xhr.setRequestHeader('Accept', ""); // IE hack
      xhr.setRequestHeader('Accept', accept);
      xhr.setRequestHeader('Accept-Language', lang);
      if (url.indexOf('-internal') !=-1) {
        try {
          xhr.withCredentials = true;
          alert('set credentials') 
        }
        catch(e) {
          alert('cannot set xhr with credentials')
        }
      }
    },

    success: function(data,status,xhr) {
      var responseText = xhr.responseText;
      var responseJSON = xhr.responseJSON;


      var t = "";
      try{
        for (var o in xhr) t += '\n'+o+':'+xhr[o];
      }
      catch(e) {
        if (e.message.indexOf('.channel')==-1)alert(e.message);
      }
      alert('Status:'+status+'\nData:['+data+']\nXHR:'+t);
      func(responseText);
    },
  }
  currentRequest = $.ajax(requestObjectJSON);
}
4

4 に答える 4

3

私はあなたの問題を完全には理解していないので、これは暗闇の中での刺し傷ですが、オリジンfile:として扱われない URL に問題がある可能性があると思います。ファイル URL から CORS を承認することさえ可能かどうかはわかりません。

于 2010-07-31T02:01:59.597 に答える
1

CORS をセキュリティで保護されたサービスで動作させるために満たすべき条件は次のとおりです。

  • サービス応答にはヘッダーが含まれている必要がありますAccess-Control-Allow-Credentials: true(「資格情報を含む要求」および「資格情報フラグが true の場合、Access-Control-Allow-Origin でワイルドカードを使用できない」を参照してください)。
  • サービス応答ヘッダーは であっAccess-Control-Allow-Originてはなりません*。アイデアは、クライアントから渡された値をヘッダーで返すことです(この投稿Originの例を参照してください)。
  • 仕様によると、OPTIONSメソッドは HTTP コード 200 を返す必要があるため、保護できません ( CORSを参照)。
  • 特定のリクエスト ヘッダーをサービスに渡す必要があるメソッドPUT/の場合 (または など)、これらのヘッダーをリストする必要があります(「ヘッダーが指定されている場合、jQuery AJAX が機能しない」を参照) 。POSTContent-TypeAcceptAccess-Control-Allow-Headers
  • JavaScriptはこのXMLHttpRequestプロパティを設定する必要があります: ( Kirbyxhr.withCredentials = true;の回答による)

Apache の全体的な構成:

# Static content:
SetEnvIf      Request_URI     ".*"                            no-jk
# RESTful service:
SetEnvIf      Request_URI     "^/backend/"                    !no-jk
SetEnvIf      Request_Method  "OPTIONS"                       no-jk
# Fallback value:
SetEnv        http_origin     "*"
SetEnvIf      Origin          "^https?://(localhost|.*\.myconpany\.org)(:[0-9]+)?$" http_origin=$0

Header        set Access-Control-Allow-Credentials    "true"
Header        set Access-Control-Allow-Origin         "%{http_origin}e"
Header        set Access-Control-Allow-Methods        "GET,POST,PUT,DELETE"
Header        set Access-Control-Allow-Headers        "Content-Type, Accept"

JkMount /* loadbalancer
于 2014-05-27T12:45:03.493 に答える
1

したがって、CORS を使用するには、モデル/コレクションに ajax プレフィルターを設定する必要があります。それ以外の場合、Cookie は送信されません。

$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
    options.xhrFields = {
      withCredentials: true
    };
});

これをモデル/コレクションの初期化関数に入れました。

于 2012-06-07T20:37:15.927 に答える
0

とのCORSfile://

The Web Origin Conceptfile://に従って、プロトコルからのオリジンを許可することで問題が発生した場合は、他のオリジンと同じ方法で行う必要があります。ブラウザのサポートに関する情報は見つかりませんでしたが、CORS をサポートしているすべてのブラウザがこれをサポートしていると思います。

Web Origin の概念は、ファイル URI スキームについて次のことを示しています。

   4.  If uri-scheme is "file", the implementation MAY return an
       implementation-defined value.

          NOTE: Historically, user agents have granted content from the
          file scheme a tremendous amount of privilege.  However,
          granting all local files such wide privileges can lead to
          privilege escalation attacks.  Some user agents have had
          success granting local files directory-based privileges, but
          this approach has not been widely adopted.  Other user agents
          use globally unique identifiers for each file URI, which is
          the most secure option.

ウィキペディアによると、ファイル URI スキームによるドメインは localhost です。アドレスバーでは省略可能ですが、allow origin ヘッダーでは省略できないと思います。そのため、ブラウザの実装でファイル URI スキームを使用したオリジンが許可されている場合はfile://localhost、許可されたオリジンに追加する必要があります。その後、すべてが適切に機能するはずです。

これが機能するはずの方法でしたが、今では現実に直面しています:

  • 現在の firefox 29.0.1 でテストしましたが、動作しませんでした。ただし、プロトコルはこの実装によってオリジンにfile://変換されます。nullだからFirefoxでnull作品。より広いドメイン リストを試してみましたが、複数のドメインを許可することはできませんでした。現在、Firefox は複数のドメインを持つリストをサポートしていないようです。
  • Chrome 35.0.1916 でテストしましたが、Firefox と同じように動作します。
  • msie 11.0.9600 でテストしました。allow blocked contentファイル プロトコルからの要求により、null オリジンを許可しない場合でも、常にボタンが表示されます。他のドメインでは、以前のブラウザーと同じように機能します。

HTTP 基本認証:

PHP と HTTP 基本認証で試した資格情報部分。

http://test.loc
ログイン時は :-)、無許可時は :-( と表示されます。

<?php

function authorized()
{
    if (empty($_SERVER['PHP_AUTH_USER']) || empty($_SERVER['PHP_AUTH_PW']))
        return false;
    return ($_SERVER['PHP_AUTH_USER'] == 'username' && $_SERVER['PHP_AUTH_PW'] == 'password');
}

function unauthorized()
{
    header('HTTP/1.1 401 Unauthorized');
    header('WWW-Authenticate: Basic realm="Restricted Area"');
    echo '<a href="http://test.loc">:-(</a>';
}

if (!isset($_GET['logout']) && authorized()) {
    echo '<a href="http://test.loc?logout=1">:-)</a>';
} else
    unauthorized();

したがって、このコードはログインとログアウトによって場所を変更します。

HTTP 基本認証を使用したクロスドメイン CORS

http://todo.loc http://test.loc
内容をクロスドメインXHR で取得して表示します。

cross domain ajax<br />
<script>
    var xhr = new XMLHttpRequest();
    xhr.open('GET', "http://test.loc", true);
    xhr.withCredentials = true;
    xhr.onreadystatechange = function (){
        if (xhr.readyState==4) {
            document.body.innerHTML += xhr.responseText;
        }
    };
    xhr.send();
</script>

http://test.locによるヘッダーが必要です。

Access-Control-Allow-Origin: http://todo.loc
Access-Control-Allow-Credentials: true

HTTP 基本認証を使用したクロススキーム CORS

file:///path/x.html http://test.loc
の内容をクロススキームXHR で取得して表示します。

cross scheme ajax<br />
<script>
    var xhr = new XMLHttpRequest();
    xhr.open('GET', "http://test.loc", true);
    xhr.withCredentials = true;
    xhr.onreadystatechange = function (){
        if (xhr.readyState==4) {
            document.body.innerHTML += xhr.responseText;
        }
    };
    xhr.send();
</script>

http://test.locによるヘッダーが必要です。

Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true

結論:

から呼び出された資格情報を使用してクロススキーム CORS をテストしましfile://たが、firefox、chrome、msie でうまく機能します。

于 2014-05-27T14:06:19.173 に答える