En-têtes de demande de contrôle d'accès, est ajouté à l'en-tête dans la demande AJAX avec jQuery

405

Je voudrais ajouter un en-tête personnalisé à une demande AJAX POST de jQuery.

J'ai essayé ceci:

$.ajax({
    type: 'POST',
    url: url,
    headers: {
        "My-First-Header":"first value",
        "My-Second-Header":"second value"
    }
    //OR
    //beforeSend: function(xhr) { 
    //  xhr.setRequestHeader("My-First-Header", "first value"); 
    //  xhr.setRequestHeader("My-Second-Header", "second value"); 
    //}
}).done(function(data) { 
    alert(data);
});

Lorsque j'envoie cette demande et que je regarde avec FireBug, je vois cet en-tête:

OPTIONS xxxx / yyyy
Hôte HTTP / 1.1 : 127.0.0.1:6666
Agent utilisateur: Mozilla / 5.0 (Windows NT 6.1; WOW64; rv: 11.0) Gecko / 20100101 Firefox / 11.0
Accepter: text / html, application / xhtml + xml, application / xml; q = 0,9, / ; q = 0,8
Accept-Language: fr, fr-fr; q = 0,8, en-us; q = 0,5, en; q = 0,3
Accept-Encoding: gzip, deflate
Connection: keep -alive
Origin: null
Access-Control-Request-Method: POST
Access-Control-Request-Headers: my-first-header, my-second-header
Pragma: no-cache
Cache-Control: no-cache

Pourquoi mes en-têtes personnalisés vont-ils à Access-Control-Request-Headers:

En-têtes de demande de contrôle d'accès: mon-premier-en-tête, mon-deuxième-en-tête

Je m'attendais à des valeurs d'en-tête comme celle-ci:

My-First-Header: première valeur
My-Second-Header: deuxième valeur

C'est possible?

doigt
la source
Le titre de la question doit indiquer que «Pour un autre domaine»
Comptable le

Réponses:

138

Ce que vous avez vu dans Firefox n'était pas la demande réelle; notez que la méthode HTTP est OPTIONS, pas POST. Il s'agissait en fait de la demande «pré-vol» que le navigateur fait pour déterminer si une demande AJAX interdomaine doit être autorisée:

http://www.w3.org/TR/cors/

L'en-tête Access-Control-Request-Headers dans la demande de pré-vol inclut la liste des en-têtes dans la demande réelle. Le serveur doit ensuite indiquer si ces en-têtes sont pris en charge dans ce contexte ou non, avant que le navigateur soumette la demande réelle.

karlgold
la source
438

Voici un exemple de définition d'un en-tête de demande dans un appel jQuery Ajax:

$.ajax({
  type: "POST",
  beforeSend: function(request) {
    request.setRequestHeader("Authority", authorizationToken);
  },
  url: "entities",
  data: "json=" + escape(JSON.stringify(createRequestObject)),
  processData: false,
  success: function(msg) {
    $("#results").append("The result =" + StringifyPretty(msg));
  }
});
milkovsky
la source
10
thx, je sais envoyer une demande Ajax avec un en-tête personnalisé. Mon problème est avec un domaine différent. Tous mes en-têtes personnalisés sont placés dans Access-Control-Request-Headers. c'est juste la sécurité dans le navigateur: inter-domaines.
fingerup
Oui, dans les requêtes inter-domaines du navigateur, cela peut entraîner des difficultés. vous pouvez toujours utiliser un script proxy pour envoyer vos demandes inter-domaines
milkovsky
Comment ajouter les en-têtes avec API KEY?
Si8
@ Si8 s'il vous plaît vérifier cet article stackoverflow.com/questions/5517281/…
milkovsky
178

Ce code ci-dessous fonctionne pour moi. J'utilise toujours des guillemets simples, et cela fonctionne très bien. Je suggère que vous n'utilisiez que des guillemets simples ou doubles, mais pas mélangés.

$.ajax({
    url: 'YourRestEndPoint',
    headers: {
        'Authorization':'Basic xxxxxxxxxxxxx',
        'X-CSRF-TOKEN':'xxxxxxxxxxxxxxxxxxxx',
        'Content-Type':'application/json'
    },
    method: 'POST',
    dataType: 'json',
    data: YourData,
    success: function(data){
      console.log('succes: '+data);
    }
  });
Graphique
la source
1
thx, je sais envoyer une demande Ajax avec un en-tête personnalisé. Mon problème est avec un domaine différent. Tous mes en-têtes personnalisés sont placés dans Access-Control-Request-Headers. c'est juste la sécurité dans le navigateur: inter-domaines.
fingerup
Merci, j'avais mis des en-têtes: "Autorisation: Basic XXXXXX" accidentellement, et iOS 9 / Safari 9 lançait SyntaxError DOM 12 sur un projet.
Mark
4
Voulez-vous dire des guillemets doubles ou simples? Je ne pense pas que quiconque utiliserait des crochets doubles.
DBS
3
Les guillemets doubles ou simples (pas les "crochets") n'ont rien à voir ici.
Pere
son X-CSRF-TOKEN pour le Laravel 5.6 et supérieur
Abdul Rahman A Samad
12

Étant donné que vous envoyez des en-têtes personnalisés, votre demande CORS n'est pas une simple demande . Le navigateur envoie donc d'abord une demande OPTIONS de contrôle en amont pour vérifier que le serveur autorise votre demande.

Entrez la description de l'image ici

Si vous activez CORS sur le serveur, votre code fonctionnera. Vous pouvez également utiliser la récupération JavaScript à la place ( ici )

Voici un exemple de configuration qui active CORS sur nginx (fichier nginx.conf):

Voici un exemple de configuration qui active CORS sur Apache (fichier .htaccess)

Kamil Kiełczewski
la source
3

Et c'est pourquoi vous ne pouvez pas créer un bot avec JavaScript, car vos options sont limitées à ce que le navigateur vous permet de faire. Vous ne pouvez pas simplement commander un navigateur qui respecte la politique CORS , que la plupart des navigateurs suivent, pour envoyer des demandes aléatoires à d'autres origines et vous permettre d'obtenir la réponse simplement!

De plus, si vous avez essayé de modifier manuellement certains en-têtes de demande, comme origin-headerdans les outils de développement fournis avec les navigateurs, le navigateur refusera votre modification et pourra envoyer une OPTIONSdemande de contrôle en amont .

le comptable
la source
-10

Essayez d'utiliser le bijou rack-cors . Et ajoutez le champ d'en-tête dans votre appel Ajax.

Jie Sun
la source