CORSを使用したIE9 jQuery AJAXが「アクセスが拒否されました」を返す


123

以下はIE以外のすべてのブラウザーで機能します(IE 9でテストしています)。

jQuery.support.cors = true;
...
        $.ajax(
            url + "messages/postMessageReadByPersonEmail",
            {
                crossDomain: true,
                data: {
                    messageId       : messageId,
                    personEmail     : personEmail
                },
                success: function() {
                    alert('marked as read');
                },
                error: function(a,b,c) {
                    alert('failed');
                },
                type: 'post'
            }
        );

を使用する別の関数がありますがdataType: 'jsonp'、このAJAX呼び出しで返されるデータは必要ありません。私の最後の手段は、それを機能させるためだけに、JSONPにラップされたジブリックを返すことです。

IEがデータを返さないCORSリクエストで失敗する理由はありますか?


提案された回答のどれも私にとってうまくいかなかったので(XDomainRequestを使用する場合はno-noであるCORSリクエストにもCookieを渡す必要がありました)、回避は次のとおりです:blog.gauffin.org/2014/04/…。救助の代行!:p
wimvds 2014年

回答:


150

これはjQueryの既知のバグです。jQueryチームは「これをコアでサポートする予定はなく、プラグインとして適しています」。(このコメントを参照してください)。IEはXMLHttpRequestを使用しませが、XDomainRequestという名前の代替オブジェクトを使用します。

そこのjQueryでこれをサポートするために利用できるプラグイン、ここで見つけることができますがhttps://github.com/jaubourg/ajaxHooks/blob/master/src/xdr.js

EDIT 関数は$.ajaxTransport、トランスポーターファクトリを登録します。トランスポーターは、内部で$.ajax要求を実行するために使用されます。したがって、私は仮定し、あなたが呼び出すことができるはずです$.ajaxいつものように。トランスポーターと拡張に関する情報は$.ajax見つけることができるここに

また、このプラグインのおそらくより良いバージョンはここにあります

他の2つの注意事項:

  1. XDomainRequestオブジェクトはIE8から導入されたもので、以下のバージョンでは機能しません。
  2. IE10からCORSは、通常のXMLHttpRequestを使用してサポートされます。

編集2:httpからhttpsへの問題

リクエストはホスティングページと同じスキームをターゲットにする必要があります

この制限は、AJAXページがhttp://example.comにある場合、ターゲットURLもHTTPで始まる必要があることを意味 します。同様に、AJAXページがhttps://example.comにある場合、ターゲットURLもHTTPSで始まる必要があります。

出典:http : //blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx


12
プラグインの「より良いバージョン」は生来のものです。私はそれを自分のページに含めただけで、私の$ .ajax呼び出しが自動的に修正されました:)もちろん、必要なヘッダーすべて整っていると仮定します。
加藤

5
dennisg回答に追加するために、xdr.jsにはバグがあります-ajaxTransportコールバックはそのままでは呼び出されません。stackoverflow.com/questions/12481560/…に従って変更する必要がありました(ajaxTransport呼び出しの最初の引数として「+ *」を追加)。
Volodymyr Otryshko 2013

4
jQuery.XDomainRequest.jsは、現在のページとリモートページが両方ともhttpまたはhttpsであることを確認します。これは、httpページからhttps APIを呼び出すことができないことを意味しますか?
アーロン

2
moonscripts github repoにリンクされていたコードが動作しない古いバージョンであることは注目に値します。raw.github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest/…
Clintm '21

3
@ Aaron、@ HariKaramSinghのコメントに追加:プロトコル(httpto https)、ドメイン(google.comto bing.com)、サブドメイン(mail.google.comto maps.google.com)、またはプロトコル(google.com:80-デフォルトのポートto google.com:8080)を変更すると、すべて「クロスドメイン」リクエストがトリガーされます。基本的/に、URL の最初の前のすべてが同一である必要があります。
アリカーン2014年

62

@dennisgによる承認済みの回答を基に、MoonScriptによるjQuery.XDomainRequest.js を使用してこれを成功させました。

次のコードは、Chrome、Firefox、IE10では正常に機能しましたが、IE9では失敗しました。スクリプトを含めるだけで、IE9で自動的に機能するようになりました。(そしておそらく8つですが、テストしていません。)

var displayTweets = function () {
    $.ajax({
        cache: false,
        type: 'GET',
        crossDomain: true,
        url: Site.config().apiRoot + '/Api/GetTwitterFeed',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        success: function (data) {
            for (var tweet in data) {
                displayTweet(data[tweet]);
            }
        }
    });
};

3
jQuery.XDomainRequest.jsプラグインは、まさに私が必要としたものでした!HTTP基本認証の背後にあるリクエストに対してiexhr.jsプラグインを機能させることができませんでしたが、XDomainRequestは魅力的に機能しました。
James Ford

これでうまくいきました。Site.config()。apiRoot +は必要ありませんでした(これはTwitter用であると想定しています...)。しかし、これを実行してくれてありがとうございます。
Nicholas Decker

@NicholasDecker Site.config()。apiRootは、APIのルートURLを取得するための実装固有のコードであり、普遍的なものや空想的なものはありませんでした。それが役に立ててうれしい!
JackMorrissey 2013年

これがうまくいくことを願っていましたが、POSTしようとしています。それが私にとって問題かどうか疑問に思います。
Jack Marchetti

1
@クラッカーPOSTでのみ問題がありますか?jQueryの後にスクリプトが読み込まれていることを再確認し、呼び出しがMoonScriptのドキュメントと一致していることを確認します。
JackMorrissey 2014年

16

「jQuery-ajaxTransport-XDomainRequest」プラグインを使用してこれを行う方法の完全な手順は、https//github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest#instructionsにあります。

このプラグインは積極的にサポートされており、HTML、JSON、XMLを処理します。ファイルは、CDNJSでホストされているので、あなたは直接追加設定なしであなたのページにスクリプトをドロップすることができます。 http://cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.1/jquery.xdomainrequest .min.js


1
これはうまくいきました-修正をドロップしてください。この問題がjQueryに存在するとは信じられませんが...ありがとうございます!
Cymen、2014年

3

問題は、IE9以前がCORSをサポートしていないことです。XDomainRequestはGET / POSTおよびtext/plain conten-typeます。ここで説明します:http ://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

したがって、すべてのHTTP動詞やJSONなどを使用する場合は、別のソリューションを使用する必要があります。IE9以下が使用されている場合、プロキシに適切にダウングレードするプロキシを作成しました。ASP.NETを使用している場合は、コードを変更する必要はありません。

解決策は2つの部分に分かれています。1つ目は、jQuery ajax処理にフックするjqueryスクリプトです。crossDomainリクエストが行われ、ブラウザがIEの場合、Webサーバーを自動的に呼び出します。

$.ajaxPrefilter(function (options, originalOptions, jqXhr) {
    if (!window.CorsProxyUrl) {
        window.CorsProxyUrl = '/corsproxy/';
    }
    // only proxy those requests
    // that are marked as crossDomain requests.
    if (!options.crossDomain) {
        return;
    }

    if (getIeVersion() && getIeVersion() < 10) {
        var url = options.url;
        options.beforeSend = function (request) {
            request.setRequestHeader("X-CorsProxy-Url", url);
        };
        options.url = window.CorsProxyUrl;
        options.crossDomain = false;
    }
});

Webサーバーでは、要求を受信し、X-CorsProxy-Url httpヘッダーから値を取得し、HTTP要求を実行して、最終的に結果を返す必要があります。

私のブログ投稿:http : //blog.gauffin.org/2014/04/how-to-use-cors-requests-in-internet-explorer-9-and-below/


1

サポートされているすべてのブラウザー(IE7 +と常連)に対する唯一のソリューションだったので、私はすべてのリクエストをJSONPにしました。正解です。あなたの答えは技術的にIE9で機能するので、正しい答えが得られます。


2
この問題を抱えている人へのメモ-この場合、<= IE7要件があり、サーバーを制御できない場合(たとえば、JSONPを使用したGET +スクリプトタグをサポートできない場合)最善の策は、JSONP呼び出しをPOSTに変換し、ブラックボックスサーバーからの応答をユーザーにストリーミングする軽量のミドルウェアサーバーです。
mikermcneil 2013年

1

MoonScriptによるソリューションに基づいて、代わりにこれを試すことができます。

https://github.com/intuit/xhr-xdr-adapter/blob/master/src/xhr-xdr-adapter.js

利点は、それが下位レベルのソリューションであるため、jQueryだけでなく、他のフレームワークを使用してIE 8/9で(可能な範囲で)CORSを有効にすることです。AngularJS、jQuery 1.xおよび2.xでの使用に成功しました。



0

この問題を解決するには、次のような.jsがajaxファイルに含まれているかどうかも確認してください。


0

開発マシンでCORS Webサービスをテストしていて、IEでのみ「アクセスが拒否されました」というエラーメッセージが表示されていました。FirefoxとChromeは問題なく動作しました。これは、ajax呼び出しでのlocalhostの使用が原因であることがわかりました。だから私のブラウザのURLは次のようなものでした:

http://my_computer.my_domain.local/CORS_Service/test.html

そして、test.html内の私のajax呼び出しは次のようなものでした:

//fails in IE 
$.ajax({
  url: "http://localhost/CORS_Service/api/Controller",
  ...
});

localhostの代わりに自分のコンピューターのIPを使用するようにajax呼び出しを変更すると、すべてが機能しました。

//Works in IE
$.ajax({
  url: "http://192.168.0.1/CORS_Service/api/Controller",
  ...
});

IE開発ツールウィンドウの[ネットワーク]タブには、CORSプリフライトOPTIONSリクエストに続いてXMLHttpRequest GETも表示されます。




-1

注意-注意

ajaxのURLには、「http://www.domain.xxx」、「http:// localhost /」、「IP >> 127.0.0.1」を使用しないでください。アドレスなしでパス(ディレクトリ)とページ名のみを使用します。

偽の状態:

var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST', 'http://www.example.com/dir/getSecurityCode.php', true);
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);

真の状態:

var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST', 'dir/getSecurityCode.php', true);   // <<--- note
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.