web-dev-qa-db-fra.com

Impossible de définir correctement l'en-tête Accepter HTTP avec jQuery

J'essaie de définir l'en-tête HTTP Accept sur "text/xml" avec ce code jQuery:

$.ajax({
    beforeSend: function(req) {
        req.setRequestHeader("Accept", "text/xml");
    },
    type: "GET",
    url: "[proper url]",
    contentType: "text/plain; charset=utf-8",
    dataType: ($.browser.msie) ? "text" : "xml",
    username: '---',
    password: '-------',                                
    success: function(data) {
        var xml;
        if (typeof data == "string") {
            alert("Data is string:" + data);
            xml = new ActiveXObject("Microsoft.XMLDOM");
            xml.async = false;
            xml.loadXML(data);
        } else {
            xml = data;
            alert("Data is not string:" + $(xml).text());
        }
        // Returned data available in object "xml"
        //alert("Status is: " + xml.statusText);
        $("#ingest_history").html($(xml).text());
    }              
});

Dans Firefox, cela fonctionne très bien.

Mais dans IE, la valeur que j'essaie de définir pour l'en-tête Accept semble être ajoutée à la fin, de sorte qu'elle devient: Accept: */*, text/xml. Cela force mon appel ajax à renvoyer la version html par opposition à la version xml que je souhaite.

Quelqu'un sait-il comment définir/effacer correctement l'en-tête Accept dans IE 8?

Mise à jour: pour une raison quelconque, les astérisques n'apparaissaient pas lorsque je les ai saisis. L'en-tête Accepter dans IE semble être: Accept: */*, text/xml.

73

J'ai également eu des problèmes avec cela, pas seulement dans IE, mais aussi dans Chrome et Safari avec jQuery 1.6.2. Cette solution semble fonctionner comme prévu dans tous les navigateurs que j'ai essayés (Chrome, Safari, IE, Firefox).

$.ajax({
    headers: { 
        Accept : "text/plain; charset=utf-8",
        "Content-Type": "text/plain; charset=utf-8"
    },
    data: "data",
    success : function(response) {
        ...
    }
})

Essayez cela si cela vous pose encore des problèmes.

70
Joel Westberg

Avec jQuery 1.5+, vous pouvez définir les en-têtes d’acceptations par dataType afin que vous puissiez faire quelque chose comme ceci:

$.ajax({
    dataType: ($.browser.msie) ? "text" : "xml",
    accepts: {
        xml: "text/xml",
        text: "text/xml"
    }
});
24
gnarf

Votre problème semble être celui décrit ici: http://www.grauw.nl/blog/entry/470 . Le problème est que la spécification XMLHttpRequest indique actuellement que les agents utilisateurs ne doivent définir aucun en-tête Accept par défaut pour la demande, de sorte que req.setRequestHeader () puisse simplement ajouter de nouveaux Accepts. Malheureusement, les navigateurs n'y adhèrent pas encore. La description du problème vous permet de tester votre navigateur pour voir s'il fonctionne correctement. Malheureusement, IE7, Chrome, Safari, Firefox et Opera échouent.

Laurens Grauw parle également des effets de la première tentative d’annulation de l’en-tête Accept avec 

setRequestHeader('Accept', '')

ou

setRequestHeader('Accept', null)

Ceux-ci pourraient aider ici.

Hackers côté serveur: si vous avez le contrôle de votre application côté serveur, vous pouvez le connecter pour qu'il renvoie toujours le code XML, ajouter la prise en charge d'un type de support personnalisé tel que "application/i-really-want-xml" ou en-tête HTTP personnalisé comme "X-Accept".

8
Jim Ferrans

Je pense que l'affiche originale aurait pu faire référence à ce lien: http://blogs.msdn.com/ieinternals/archive/2009/07/01/IE-and-the-Accept-Header.aspx cependant cela n'explique pas le comportement que vous voyez. 

En soi, IE n'a pas le comportement que vous décrivez et la définition de l'en-tête Accept via XMLHTTPRequest devrait fonctionner correctement. J'ai testé dans IE8 pour confirmer.

Il est possible qu'il y ait un problème dans votre version de jQuery, ou peut-être avez-vous des plugins qui gênent votre trafic?

2
EricLaw

Bien que la documentation ne stipule pas que cela doit être fait, c'est ce qui a fonctionné pour moi. 

 jQuery.ajax({
    type: "POST",
    url: "...",
    data: ...,
    contentType: "text/xml",
    beforeSend: function(req) {
    req.setRequestHeader("Accept", "text/xml");
    },  ...});
1
Adam

Je ne crois pas que IE (quelle que soit sa version) joue bien avec l'en-tête Accept. Voir ce lien: [ http://blogs.msdn.com/ieinternals/archive/2009/07/01/IE-and-the-Accept-Header.aspx]

Une solution possible pourrait être de vérifier l'agent utilisateur pour voir s'il s'agit d'Internet Explorer. Si c'est le cas, vérifiez la présence de text/xml. 

Bonne chance!

Modifier:

Opps sur le lien. Mon intuition était IE ajoute toujours le / et la définition de l'en-tête d'acceptation n'ajoute que le type mime souhaité après le /.

0
BStruthers