CORS ile IE9 jQuery AJAX, "Erişim reddedildi" döndürüyor


123

Aşağıdakiler IE dışındaki tüm tarayıcılarda çalışır (IE 9'da test ediyorum).

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'
            }
        );

Kullanan başka bir işlevim var dataType: 'jsonp', ancak bu AJAX çağrısında döndürülen herhangi bir veriye ihtiyacım yok. Son çarem, JSONP ile sarılmış biraz titiz bir ifadeyi sadece çalışmasını sağlamak için iade etmek olacak.

IE'nin veri döndürmeyen bir CORS talebiyle neden hata yaptığına dair bir fikriniz var mı?


Önerilen yanıtların hiçbiri benim için işe yaramadığı için (çerezleri CORS isteğine de iletmek zorunda kaldım, ki bu XDomainRequest'i kullanırken hayırdır), işte bir çözüm : blog.gauffin.org/2014/04/… . Kurtarma için vekaleten! : p
wimvds

Yanıtlar:


150

Bu, jQuery ile ilgili bilinen bir hatadır . JQuery ekibinin "bunu çekirdek olarak destekleme planı yoktur ve eklenti olarak daha uygundur." ( Bu yoruma bakın ). IE , XMLHttpRequest'i değil , XDomainRequest adlı alternatif bir nesneyi kullanır .

Bunu jQuery'de destekleyecek bir eklenti var , burada bulunabilir : https://github.com/jaubourg/ajaxHooks/blob/master/src/xdr.js

DÜZENLE İşlev, $.ajaxTransportbir taşıyıcı fabrikasını kaydeder. Bir taşıyıcı kullanıldığı içten tarafından $.ajaxistekleri yerine getirmektir. Bu nedenle, her zamanki gibi arayabileceğinizi varsayıyorum$.ajax . Taşıyıcılar ve uzatma ile ilgili bilgiler burada$.ajax bulunabilir .

Ayrıca, bu eklentinin belki de daha iyi bir sürümü burada bulunabilir .

Diğer iki not:

  1. XDomainRequest nesnesi IE8'den tanıtıldı ve aşağıdaki sürümlerde çalışmayacaktır.
  2. IE10'dan itibaren CORS, normal bir XMLHttpRequest kullanılarak desteklenecektir .

Düzenleme 2: http'den https'ye sorun

İstekler, barındırma sayfasıyla aynı şemaya hedeflenmelidir

Bu kısıtlama, AJAX sayfanız http: //example.com'da ise, hedef URL'nizin de HTTP ile başlaması gerektiği anlamına gelir . Benzer şekilde, AJAX sayfanız https://example.com adresindeyse , hedef URL'niz de HTTPS ile başlamalıdır.

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


12
Eklentinin "daha iyi sürümü" doğuştan gelir; Sadece sayfama ekledim ve $ .ajax aramalarımı otomatik olarak düzeltti :) Tabii ki, gerekli tüm başlıklara sahip olduğunuzu varsayarak .
Kato

5
Dennisg yanıtına eklemek için, xdr.js'de bir hata var - ajaxTransport geri araması olduğu gibi çağrılmayacak. Bunu stackoverflow.com/questions/12481560/… uyarınca değiştirmek zorunda kaldım (ajaxTransport çağrısının ilk argümanı olarak "+ *" eklendi).
Volodymyr Otryshko

4
jQuery.XDomainRequest.js, geçerli sayfanın ve uzak sayfanın hem http hem de https olmasını sağlar. Bu, bir http sayfasından bir https API'sine çağrı yapamayacağınız anlamına mı geliyor?
Aaron

2
Moonscripts github repo'suna bağlanan kodun çalışmayan eski bir sürüm olduğunu belirtmek gerekir. En son sürümü şu adresten edindiğinizden
Clintm

3
@Aaron için en HariKaramSingh @ yorumum ekleyerek: Değişen protokolleri ( httpiçin https), etki alanları ( google.comiçin bing.com), alt alan adları ( mail.google.comiçin maps.google.com) veya protokolleri ( google.com:80- varsayılan bağlantı noktası google.com:8080) tüm tetikleyici bir "alanları arası" isteği olacaktır. Temelde /URL'nizde ilkinden önceki her şeyin aynı olması gerekir.
allicarn

62

@Dennisg tarafından kabul edilen cevabı temel alarak, bunu MoonScript tarafından jQuery.XDomainRequest.js kullanarak başarıyla gerçekleştirdim .

Aşağıdaki kod Chrome, Firefox ve IE10'da düzgün çalıştı, ancak IE9'da başarısız oldu. Sadece betiği ekledim ve şimdi otomatik olarak IE9'da çalışıyor. (Ve muhtemelen 8, ama test etmedim.)

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 eklentisi tam da ihtiyacım olan şeydi! İexhr.js eklentisinin HTTP Temel Kimlik Doğrulamasının arkasındaki istekler için çalışmasını sağlayamadım, ancak XDomainRequest bir cazibe gibi çalıştı!
James Ford

Bu benim için çalıştı. Site.config (). ApiRoot + 'a ihtiyacım yoktu (twitter için olduğunu varsayıyorum ....) Ama harika çalışıyor, bunu yaptığınız için teşekkürler.
Nicholas Decker

@NicholasDecker Site.config (). ApiRoot, evrensel veya süslü bir şey değil, API'nin kök URL'sini almak için yalnızca uygulamaya özgü bir koddu. Yardımcı olduğuna sevindim!
JackMorrissey

Bunun benim için işe yarayacağını umuyordum ama POST yapmaya çalışıyorum. Acaba benim için sorun bu mu?
Jack Marchetti

1
@cracker Yalnızca POST ile ilgili sorun mu yaşıyorsunuz? Komut dosyasının jQuery'den sonra yüklendiğini ve aramanızın MoonScript belgelerine uyduğunu iki kez kontrol edin.
JackMorrissey

16

"JQuery-ajaxTransport-XDomainRequest" eklentisini kullanarak bunun nasıl yapılacağına ilişkin eksiksiz talimatlar şurada bulunabilir: https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest#instructions

Bu eklenti aktif olarak desteklenir ve HTML, JSON ve XML ile çalışır. Dosya aynı zamanda CDNJS'de de barındırıldığından, başka bir kurulum yapmadan komut dosyasını sayfanıza doğrudan bırakabilirsiniz: http://cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.1/jquery.xdomainrequest .min.js


1
Bu harika çalıştı - düzeltmede düşüş. Bu sorunun jQuery'de olması inanılmaz ama ... Teşekkürler!
Cymen

3

Sorun, IE9 ve altının CORS'u desteklememesidir. XDomainRequest yalnızca GET / POST'u ve text/plainburada açıklanan conten türünü destekler : http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

Dolayısıyla, tüm HTTP fiillerini ve / veya json vb. Kullanmak istiyorsanız, başka bir çözüm kullanmanız gerekir. IE9 veya daha azı kullanılırsa, incelikle proxy'ye geçecek bir proxy yazdım. ASP.NET kullanıyorsanız, kodunuzu hiç değiştirmeniz gerekmez.

Çözüm iki bölümden oluşmaktadır. İlki, jQuery ajax işlemesine bağlanan bir jquery betiğidir. Bir crossDomain isteği yapılırsa ve tarayıcı IE ise otomatik olarak web sunucusunu arayacaktır:

$.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 sunucunuzda isteği almanız, değeri X-CorsProxy-Url http başlığından almanız ve bir HTTP isteği yapmanız ve sonunda sonucu döndürmeniz gerekir.

Blog gönderim: http://blog.gauffin.org/2014/04/how-to-use-cors-requests-in-internet-explorer-9-and-below/


1

Tüm istekleri JSONP yaptım çünkü desteklenen tüm tarayıcılarımız (IE7 + ve normaller) için tek çözümdü. Unutmayın, cevabınız teknik olarak IE9 için işe yarıyor, bu yüzden doğru cevaba sahipsiniz.


2
Bu sorunu yaşayan herkese bir not - bu durumda, bir <= IE7 gereksiniminiz varsa ve sunucu üzerinde kontrolünüz yoksa (örneğin, JSONP ile GET + komut dosyası etiketlerini destekleyemezseniz) en iyi bahis, JSONP çağrısını bir POST'a çeviren ve kara kutu sunucusundan gelen yanıtı kullanıcıya geri aktaran hafif bir ara yazılım sunucusudur.
mikermcneil



0

Bu sorunu çözmek için, ajax dosyanıza şu adla .js ekleyip eklemediğinizi de kontrol edin: ajax.php dosyama shadowbox.js eklerken Erişim reddedildi hatası aldım


0

Geliştirici makinemde bir CORS web hizmetini test ediyordum ve yalnızca IE'de "Erişim reddedildi" hata mesajını alıyordum. Firefox ve Chrome iyi çalıştı. Bunun ajax çağrısında localhost kullanmamdan kaynaklandığı ortaya çıktı! Yani tarayıcımın URL'si şöyle bir şeydi:

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

ve test.html içindeki ajax çağrım şöyle bir şeydi:

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

Ajax çağrısını localhost yerine bilgisayarımın IP'sini kullanacak şekilde değiştirdiğimde her şey çalıştı.

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

IE geliştirici araçları penceresi "Ağ" sekmesi aynı zamanda CORS Preflight OPTIONS isteğini ve ardından XMLHttpRequest GET'i de gösterir, bu tam olarak görmeyi beklediğim şeydir.




-1

Not - Not

ajax'ta URL için " http://www.domain.xxx " veya " http: // localhost / " veya "IP >> 127.0.0.1" kullanmayın. adres olmadan yalnızca yol (dizin) ve sayfa adını kullanın.

yanlış durum:

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);

gerçek durum:

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);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.