web-dev-qa-db-fra.com

Ajouter un en-tête dans la demande AJAX avec jQuery

J'aimerais 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 HTTP/1.1
Hôte: 127.0.0.1:6666
Utilisateur-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; version: 11.0) Gecko/20100101 Firefox/11.0
Accepter: texte/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
Connexion: garder en vie
Origine: null
Méthode de demande de contrôle d'accès: POST
en-têtes de demande d'accès-contrôle: mon-premier-en-tête, mon-deuxième-en-tête
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 à un en-tête comme celui-ci:

Mon-premier-en-tête: première valeur
Mon-deuxième-en-tête: deuxième valeur

C'est possible?

365
fingerup

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 requête "pré-vol" du navigateur pour déterminer si une requête interdomaine AJAX devait être autorisée:

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

L'en-tête de contrôle d'accès-demande-en-têtes 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 ou non pris en charge dans ce contexte, avant que le navigateur ne soumette la demande.

132
karlgold

Voici un exemple pour définir 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));
  }
});
412
milkovsky

Ce code ci-dessous fonctionne pour moi. Je n'utilise toujours que des guillemets simples, et cela fonctionne bien. Je suggère que vous devriez utiliser uniquement des guillemets simples OR uniquement des guillemets doubles, mais non 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);
    }
  });

J'espère que ça répond à ta question...

146
G-raph

Parce que vous envoyez des en-têtes personnalisés, votre demande CORS est REQUÊTE NON SIMPLE donc le navigateur envoie d'abord la demande OPTIONS de prefilight pour vérifier que le serveur autorise votre demande.

enter image description here

Si vous activez CORS sur le serveur, votre code fonctionnera. Vous pouvez également utiliser js fetch à la place ( here )

let url='https://server.test-cors.org/server?enable=true&status=200&methods=POST&headers=My-First-Header,My-Second-Header';


$.ajax({
    type: 'POST',
    url: url,
    headers: {
        "My-First-Header":"first value",
        "My-Second-Header":"second value"
    }
}).done(function(data) { 
    alert(data[0].request.httpMethod + ' was send - open chrome console> network to see it');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

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

location ~ ^/index\.php(/|$) {
   ...
    add_header 'Access-Control-Allow-Origin' "$http_Origin" always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;
    if ($request_method = OPTIONS) {
        add_header 'Access-Control-Allow-Origin' "$http_Origin"; # DO NOT remove THIS LINES (doubled with outside 'if' above)
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'My-First-Header,My-Second-Header,Authorization,Content-Type,Accept,Origin';
        add_header 'Content-Length' 0;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        return 204;
    }
}

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

# ------------------------------------------------------------------------------
# | Cross-domain AJAX requests                                                 |
# ------------------------------------------------------------------------------

# Enable cross-Origin AJAX requests.
# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
# http://enable-cors.org/

# <IfModule mod_headers.c>
#    Header set Access-Control-Allow-Origin "*"
# </IfModule>

#Header set Access-Control-Allow-Origin "http://example.com:3000"
#Header always set Access-Control-Allow-Credentials "true"

Header set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Allow-Headers "My-First-Header,My-Second-Header,Authorization, content-type, csrf-token"
5

Et c’est pourquoi vous ne pouvez pas créer de 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 suit la politique CORS, utilisée par la plupart des navigateurs, d’envoyer des requêtes aléatoires à d’autres origines et de vous permettre d’obtenir une réponse aussi simple!

De plus, si vous avez essayé de modifier manuellement certains en-têtes de requête tels que Origin-header à partir des outils de développement fournis avec les navigateurs, le navigateur refusera votre modification et pourra envoyer une demande de contrôle en amont OPTIONS.

1
the accountant