web-dev-qa-db-fra.com

IE9 jQuery AJAX avec CORS renvoie "L'accès est refusé"

Ce qui suit fonctionne dans tous les navigateurs sauf IE (je teste dans 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'
            }
        );

J'ai une autre fonction qui utilise dataType: 'jsonp', mais je n'ai besoin d'aucune donnée retournée lors de cet appel AJAX. Mon dernier recours sera de renvoyer du jibberish enveloppé dans du JSONP, juste pour le faire fonctionner.

Des idées pour lesquelles IE se trompe avec une demande CORS qui ne renvoie aucune donnée?

123
Garrett

Ceci est connu bug avec jQuery. L’équipe de jQuery n’a "pas prévu de prendre en charge cette fonctionnalité et est mieux adaptée en tant que plug-in". (Voir ce commentaire ). IE ne not utilisez XMLHttpRequest , mais un objet alternatif nommé XDomainRequest .

There is un plugin disponible pour supporter cela dans jQuery, qui peut être trouvé ici : https://github.com/jaubourg/ ajaxHooks/blob/master/src/xdr.js

EDIT La fonction $.ajaxTransport enregistre une fabrique de transporteurs. Un transporteur est utilisé en interne par $.ajax pour effectuer des requêtes. Par conséquent, je suppose vous devriez pouvoir appeler $.ajax comme d'habitude. Des informations sur les transporteurs et l'extension $.ajax peuvent être trouvées ici .

En outre, une version peut-être meilleure de ce plugin peut être trouvée ici .

Deux autres notes:

  1. L'objet XDomainRequest était introduit à partir de IE8 et ne fonctionnera pas dans les versions ci-dessous.
  2. À partir de IE10, CORS sera supporté avec un XMLHttpRequest normal .

Edit 2: http to https problem

Les demandes doivent être ciblées sur le même schéma que la page d'hébergement

Cette restriction signifie que si votre page AJAX est à http://example.com , votre URL cible doit également commencer par HTTP. De même, si votre page AJAX est à https://example.com , votre URL cible doit également commencer par HTTPS.

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

149
dennisg

En me basant sur la réponse acceptée de @dennisg, j’ai réussi à le faire avec jQuery.XDomainRequest.js de MoonScript.

Le code suivant a fonctionné correctement dans Chrome, Firefox et IE10, mais a échoué dans IE9. J'ai simplement inclus le script et cela fonctionne maintenant automatiquement dans IE9. (Et probablement 8, mais je ne l'ai pas testé.)

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]);
            }
        }
    });
};
62
JackMorrissey

Des instructions complètes sur la procédure à suivre à l'aide du plug-in "jQuery-ajaxTransport-XDomainRequest" sont disponibles à l'adresse suivante: https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest#instructions

Ce plugin est activement pris en charge et gère HTML, JSON et XML. Le fichier est également hébergé sur CDNJS, vous pouvez donc directement déposer le script dans votre page sans configuration supplémentaire: http://cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.1 /jquery.xdomainrequest.min.js

16
MoonScript

Le problème est que IE9 et les versions antérieures ne prennent pas en charge CORS. XDomainRequest ne prend en charge que GET/POST et le text/plain tel que décrit ici: http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions -limitations-and-workarounds.aspx

Donc, si vous voulez utiliser tous les verbes HTTP et/ou json, etc., vous devez utiliser une autre solution. J'ai écrit un proxy qui rétrogradera gracieusement au proxy si IE9 ou moins est utilisé. Vous n'êtes pas obligé de changer votre code si vous utilisez ASP.NET.

La solution est en deux parties. Le premier est un script jQuery qui se connecte au traitement ajax de jQuery. Il appellera automatiquement le serveur Web si une demande crossDomain est faite et que le navigateur est IE:

$.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;
    }
});

Sur votre serveur Web, vous devez recevoir la demande, obtenir la valeur de l'en-tête http X-CorsProxy-Url, effectuer une demande HTTP et renvoyer le résultat.

Mon article de blog: http://blog.gauffin.org/2014/04/how-to-use-cors-requests-in-internet-Explorer-9-and-below/

3
jgauffin

Obtention d'un JSON interdomaine avec jQuery dans Internet Explorer 8 et les versions plus récentes

Lien très utile:

http://graphicmaniacs.com/note/getting-a-cross-domain-json-with-jquery-in-internet-Explorer-8-and-later/

Peut aider avec la peine de retourner JSON à partir d'une demande de domaine X.

J'espère que ça aide quelqu'un.

1
jmarcosSF

En vous appuyant sur la solution de MoonScript, vous pouvez essayer ceci à la place:

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

L'avantage est que, puisqu'il s'agit d'une solution de niveau inférieur, elle permettra à CORS (dans la mesure du possible) sur IE 8/9 de fonctionner avec d'autres frameworks, pas seulement avec jQuery. J'ai eu du succès avec AngularJS, ainsi que jQuery 1.x et 2.x.

1
yanni

Je viens de faire toutes les demandes JSONP car c'était la seule solution pour tous les navigateurs pris en charge (IE7 + et les habitués). Remarquez que votre réponse fonctionne techniquement pour IE9 afin que vous ayez la bonne réponse.

1
Garrett

Pour résoudre ce problème, vérifiez également si vous avez des fichiers .js inclus dans votre fichier ajax appelé: J'ai reçu une erreur d'accès refusé lors de l'inclusion de shadowbox.js dans mon fichier ajax.php.

0
hacklover

Mise à jour à partir de début 2015. xDomain est une bibliothèque largement utilisée pour prendre en charge CORS sur IE9 avec un codage supplémentaire limité.

https://github.com/jpillora/xdomain

0
Bernard

Je testais un service Web CORS sur ma machine de développement et le message d'erreur "Accès refusé" n'apparaissait que dans IE. Firefox et Chrome ont bien fonctionné. Il s’avère que cela a été causé par mon utilisation de localhost dans l’appel ajax! Donc, l'URL de mon navigateur était quelque chose comme:

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

et mon appel ajax à l'intérieur de test.html ressemblait à quelque chose comme:

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

Tout a fonctionné une fois que j'ai modifié l'appel ajax pour qu'il utilise l'adresse IP de mon ordinateur plutôt que localhost.

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

L'onglet "Réseau" de la fenêtre IE de la bibliothèque d'outils de développement affiche également la demande d'OPTIONS de contrôle en amont de CORS suivie de XMLHttpRequest GET, qui correspond exactement à ce à quoi je m'attendais.

0
jwill212

Essayez d'utiliser jquery-transport-xdr plugin jQuery pour les demandes CORS dans IE8/9.

0
Gordon Freeman