web-dev-qa-db-ja.com

Jquery $ .ajaxは、クロスドメインコールでIEで失敗します

$.ajaxを使用してクロスドメインリクエストを行っています。 FirefoxおよびChromeで動作しますが、IE 7または8で呼び出しを発行しません。

  1. JSONとJSONPを使用しました(カスタム制限により使用を停止しました)。
  2. 私はすでに私のサイトでAllow-access-control-Originヘッダーを使用しています。 (これらがなければ、ChromeとFirefoxはリクエストを成功させませんでした。)
  3. 私はすでに試しました https://developer.mozilla.org/en/http_access_control

コード:

$.ajax({
    type: 'GET',
    url: "http://anotherdomain.com/Service/GetControl?id=" + zoneID,
    cache: false,
    contentType: "application/x-www-form-urlencoded",
    async: false,
    beforeSend: function (request) {
        //alert('before send');
        //request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
        //request.setRequestHeader("X-PINGOTHER", "pingpong");
    } ,
    success: function (data, status) {
        //alert("Data returned :" + data);
        //alert("Status :" + status);
        if (status == "success" && data != "")
            $("#" + div.id).append(data);
        else
            $("#" + div.id).attr("style", "display:none;");
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
        alert(textStatus);
        alert(errorThrown);
    }
});

複数のサイトに存在するさまざまなヒントを試しましたが、まだ運がありません。

64
Furqan Hameedi

IEの問題がクロスゾーンリクエストを許可するセキュリティゾーンを定義していないことに依存しているかどうかを確認できますか? このMicrosoftページを参照 説明については。

OTOH、 このページ IE7とEarilerはクロスドメインコールを実行できないが、IE8はJQueryが使用するXMLHttpRequestとは異なるオブジェクトを使用して実行できることを述べています。 XDomainRequestが機能するかどうかを確認できますか?

編集(2013-08-22)

2番目のリンクは停止しているため、ここで wayback machine から取得した情報の一部を書いています。

サポートされるXDomainRequest:IE8

XMLHttpRequestのCORSバージョンを実装するのではなく、IEチームはXDomainRequestという名前の独自のオブジェクトを使用しました。おそらく最も重要です)。

この実装には、いくつかの制限があります。たとえば、このオブジェクトを使用する場合、Cookieは送信されません。これは、サーバー側のCookieベースのセッションの頭痛の種になる可能性があります。また、ContentTypeを設定できません。これにより、ASP.NETおよびその他のサーバー側言語で問題が発生します( http://www.actionmonitor.co.uk/NewsItem.aspx?id=5 を参照してください) )。

var xdr = new XDomainRequest();
xdr.onload = function() { alert("READY"); };
xdr.open("GET", "script.html");
xdr.send();
32
Luciano

IE8およびIE9の場合、XDomainRequest(XDR)を使用する必要があります。以下を見ると、$。ajaxと同様の形式になっていることがわかります。私の研究によると、IE6と7でこのクロスドメインを動作させることはできません(これに対する回避策を探しています)。 XDRは最初にIE8で登場しました(IE9でも同様です)。したがって、基本的に最初に、6/7をテストし、AJAXを実行しません。

IE10 +は通常、他のすべてのブラウザと同じようにクロスドメインを実行できます(おめでとう...ため息)

その後、else ifは、ウィンドウ内で 'XDomainRequestをテストし(ブラウザスニッフィングよりも明らかに優れている)、JSON AJAXリクエストをそのように実行します。

お役に立てれば!!これをすべて最初から把握するために永遠に私を連れて行った

XDomainRequestオブジェクトに関する情報

// call with your url (with parameters) 
// 2nd param is your callback function (which will be passed the json DATA back)

crossDomainAjax('http://www.somecrossdomaincall.com/?blah=123', function (data) {
    // success logic
});

function crossDomainAjax (url, successCallback) {

    // IE8 & 9 only Cross domain JSON GET request
    if ('XDomainRequest' in window && window.XDomainRequest !== null) {

        var xdr = new XDomainRequest(); // Use Microsoft XDR
        xdr.open('get', url);
        xdr.onload = function () {
            var dom  = new ActiveXObject('Microsoft.XMLDOM'),
                JSON = $.parseJSON(xdr.responseText);

            dom.async = false;

            if (JSON == null || typeof (JSON) == 'undefined') {
                JSON = $.parseJSON(data.firstChild.textContent);
            }

            successCallback(JSON); // internal function
        };

        xdr.onerror = function() {
            _result = false;  
        };

        xdr.send();
    } 

    // IE7 and lower can't do cross domain
    else if (navigator.userAgent.indexOf('MSIE') != -1 &&
             parseInt(navigator.userAgent.match(/MSIE ([\d.]+)/)[1], 10) < 8) {
       return false;
    }    

    // Do normal jQuery AJAX for everything else          
    else {
        $.ajax({
            url: url,
            cache: false,
            dataType: 'json',
            type: 'GET',
            async: false, // must be set to false
            success: function (data, success) {
                successCallback(data);
            }
        });
    }
}

Jqueryがこれを行います。唯一のことは$.support.cors = true;を設定することです。その後、jqueryユーザーのすべてのブラウザでクロスドメインリクエストが正常に機能します。

23
Anand

このjQueryプラグインをインストールするだけです:jQuery Cross-Domain AJAX

この1.4kbプラグインはInternet Explorer 8および9ですぐに動作します。

JQueryの後にプラグインを含め、通常どおりajaxリクエストを呼び出します。他に何も必要ありません。

20
Bradley Flood

IEのjqueryにトランスポートを追加します。 (最後にこのコードをスクリプトに追加するだけです)

$.ajaxTransport("+*", function( options, originalOptions, jqXHR ) {

    if(jQuery.browser.msie && window.XDomainRequest) {

        var xdr;

        return {

            send: function( headers, completeCallback ) {

                // Use Microsoft XDR
                xdr = new XDomainRequest();

                xdr.open("get", options.url);

                xdr.onload = function() {

                    if(this.contentType.match(/\/xml/)){

                        var dom = new ActiveXObject("Microsoft.XMLDOM");
                        dom.async = false;
                        dom.loadXML(this.responseText);
                        completeCallback(200, "success", [dom]);

                    }else{

                        completeCallback(200, "success", [this.responseText]);

                    }

                };

                xdr.ontimeout = function(){
                    completeCallback(408, "error", ["The request timed out."]);
                };

                xdr.onerror = function(){
                    completeCallback(404, "error", ["The requested resource could not be found."]);
                };

                xdr.send();
          },
          abort: function() {
              if(xdr)xdr.abort();
          }
        };
      }
    });

これにより、クロスドメインAJAXリクエストで失敗するJquery $ .ajaxの問題が解決しました。

乾杯。

7
Jay Dave

ここに来ている他の人は読むのが良いかもしれません http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx which XDomainRequestの制限について話す

5
Ayush Gupta

JQuery 2.0を使用してまだこの問題を抱えている可能性のある人(私は知っています)に対して、Jay DaveはjQueryの最善の回避策を書きましたが、彼のコードに追加すべきことがいくつかあります。

  • リクエストに同じプロトコル(HTTP-> HTTPまたはHTTPS-> HTTPS)を使用していることを確認してください。AyushGuptaは問題を知るためのリンクを提供しました
  • no-op関数を使用して "onprogress"イベントを処理します(これにより、サーバーから最初のビットを受信した後、IEがリクエストを中止するのを防ぎます。

完全なコードは次のとおりです。

// add ajax transport method for cross domain requests when using IE9
if('XDomainRequest' in window && window.XDomainRequest !== null) {
   $.ajaxTransport("+*", function( options, originalOptions, jqXHR ) {
       // verify if we need to do a cross domain request
       // if not return so we don't break same domain requests
       if (typeof options.crossDomain === 'undefined' || !options.crossDomain) {
           return;
       }

        var xdr;

        return {
            send: function( headers, completeCallback ) {
                // Use Microsoft XDR
                xdr = new XDomainRequest();
                xdr.open("get", options.url); // NOTE: make sure protocols are the same otherwise this will fail silently
                xdr.onload = function() {
                    if(this.contentType.match(/\/xml/)){
                        var dom = new ActiveXObject("Microsoft.XMLDOM");
                        dom.async = false;
                        dom.loadXML(this.responseText);
                        completeCallback(200, "success", [dom]);
                    } else {
                        completeCallback(200, "success", [this.responseText]);
                    }
                };

                xdr.onprogress = function() {};

                xdr.ontimeout = function(){
                    completeCallback(408, "error", ["The request timed out."]);
                };

                xdr.onerror = function(){
                    completeCallback(404, "error", ["The requested resource could not be found."]);
                };

                xdr.send();
            },
            abort: function() {
                if(xdr) xdr.abort();
            }
        };
    });
}
3
alecs.popa

「?callback =?」を追加するだけです(または「&callback =?」)をURLに追加:

$.getJSON({
    url:myUrl + "?callback=?",
    data: myData,
    success: function(data){
        /*My function stuff*/        
    }
});

(上記のようにクロスドメイン用に他のすべてを適切に設定して)呼び出しを行うと、適切なJSONPフォーマットがトリガーされます。

より詳細な説明は、答え ここ にあります。

2
Randy Hall

注、追加

$.support.cors = true;

iE8で$ .ajax呼び出しを強制するには十分でした

2
jpantona

@Furqan HTTP POSTメソッドでこれをテストしたかどうかを教えてください

私も同じような状況に取り組んでいますが、POST異なるドメインへのデータはできません。

しかし、 this を読んだ後は非常に簡単でした...唯一のことは、古いブラウザについて忘れなければならないことです。 POST上記の同じURLからのメソッドをクイックリファレンスとして送信するコードを提供しています。

function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
    xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){
    xhr = new XDomainRequest();
    xhr.open(method, url);
} else {
    xhr = null;
}
return xhr;
}

var request = createCORSRequest("POST", "http://www.sanshark.com/");
var content = "name=sandesh&lastname=daddi";
if (request){
    request.onload = function(){
    //do something with request.responseText
   alert(request.responseText);
};

 request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            request.setRequestHeader("Content-length", content.length);
            request.send(content);
}
1
Sandesh Daddi

マイクロソフトは常に(少なくともIEで)自己敗北の溝を耕しています。

http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-Origin-resource-sharing/

CORSはIE8のXDomainRequestで機能します。ただし、IE 8はプリフライトまたは認証済みリクエストをサポートしませんが、Firefox 3.5 +、Safari 4+、およびChromeはすべてこのようなリクエストをサポートします。

0
Raman

IE9でも同様の問題が発生し、CORS呼び出しの一部は中断され、他の呼び出しは中断されませんでした。私のアプリもpromiseインターフェイスに依存しているため、上記のXDomainRequestの提案は必要なものではなかったため、IE9のservice.get回避策に遅延を追加しました。うまくいけば、それがこの問題に出くわした他の誰かに役立つことを願っています。 :

    get: function (url) {
        if ('XDomainRequest' in window && window.XDomainRequest !== null) {
            var deferred = $.Deferred();
            var xdr      = new XDomainRequest();

            xdr.open("get", url);

            xdr.onload = function() {
              json = xdr.responseText;
              parsed_json = $.parseJSON(json);
              deferred.resolve(parsed_json);
            }

            xdr.send();
            return deferred;
        } else {
            return $.ajax({
                url: url,
                type: 'GET',
                dataType: 'json',
                crossDomain: true
            });
        }
    }
0
David Savage

IEでも同じ問題がありますが、次のものを置き換えて解決しました。

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

したがって、基本的にjqueryバージョンをアップグレードします。

0
KingBowen