web-dev-qa-db-fra.com

Le champ d'en-tête de demande Access-Control-Allow-Headers n'est pas autorisé par lui-même dans la réponse de contrôle en amont

J'ai rencontré plusieurs fois les problèmes de la SCRO et je peux généralement y remédier, mais je veux vraiment comprendre en le voyant à partir d'un paradigme de pile MEAN. 

Auparavant, j’avais simplement ajouté un middleware dans mon serveur express pour récupérer ces informations, mais il semble qu’il existe une sorte de pré-hook qui écarte mes requêtes. 

Le champ d'en-tête de demande Access-Control-Allow-Headers n'est pas autorisé par Access-Control-Allow-Headers dans la réponse de contrôle en amont

J'ai supposé que je pouvais faire ceci:

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Headers","*")
})

ou l'équivalent, mais cela ne semble pas résoudre le problème. J'ai aussi bien sûr essayé

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Headers","Access-Control-Allow-Headers")
})

Toujours pas de chance.

162
mibbit

Lorsque vous commencez à vous amuser avec des en-têtes de requête personnalisés, vous obtenez un contrôle en amont CORS. Il s'agit d'une demande qui utilise le verbe HTTP OPTIONS et comprend plusieurs en-têtes, dont l'un est Access-Control-Request-Headers, qui répertorie les en-têtes que le client souhaite inclure dans la demande.

Vous devez répondre à ce contrôle en amont avec les en-têtes CORS appropriés pour que cela fonctionne. L'un d'eux est en effet Access-Control-Allow-Headers. Cet en-tête doit contenir les mêmes valeurs que l'en-tête Access-Control-Request-Headers contenu (ou plus).

https://fetch.spec.whatwg.org/#http-cors-protocol explique cette configuration plus en détail.

166
Anne

C’est ce que vous devez ajouter pour que cela fonctionne.

    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
    response.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");

Le navigateur envoie une demande de contrôle en amont (avec le type de méthode OPTIONS) pour vérifier si l'accès au service hébergé sur le serveur est autorisé à partir du navigateur sur un autre domaine. En réponse à la demande de contrôle en amont, si vous injectez les en-têtes ci-dessus, le navigateur comprend qu'il est correct d'effectuer d'autres appels et que je recevrai une réponse valide à mon appel GET/POST actuel. vous pouvez contraindre le domaine auquel l'accès est accordé en utilisant Access-Control-Allow-Origin "," localhost, xvz.com "au lieu de *. (* accordera l'accès à tous les domaines).

79
manish arora

Ce problème résolu avec 

 "Origin, X-Requested-With, Content-Type, Accept, Authorization"

Particulier dans mon projet (express.js/nodejs) 

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
  next();
});

Mettre à jour: 

Every time error: Access-Control-Allow-Headers is not allowed by itself in preflight response error vous pouvez voir ce qui ne va pas avec outil de développement chrome :
 enter image description here

l'erreur ci-dessus est manquante Content-Type donc ajoutez la chaîne Content-Type à Access-Control-Allow-Headers

54
nguyên

La réponse acceptée est ok, mais j'ai eu du mal à la comprendre. Voici donc un exemple simple pour le clarifier.

Dans ma demande ajax, j'avais un en-tête d'autorisation standard. 

    $$(document).on('ajaxStart', function(e){
    var auth_token = localStorage.getItem(SB_TOKEN_MOBILE);
    if( auth_token ) {
        var xhr = e.detail.xhr;

        xhr.setRequestHeader('**Authorization**', 'Bearer ' + auth_token);
    }

Ce code produit l'erreur dans la question. Ce que je devais faire sur mon serveur nodejs était d'ajouter une autorisation dans les en-têtes autorisés:

res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,**Authorization**');
14
user732456

Pour ajouter aux autres réponses. J'ai eu le même problème et c'est le code que j'ai utilisé dans mon serveur express pour autoriser les appels REST:

  app.all('*', function(req, res, next) {
    res.header('Access-Control-Allow-Origin', 'URLs to trust of allow');
    res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    if ('OPTIONS' == req.method) {
    res.sendStatus(200);
    } else {
      next();
    }
  });

En gros, ce code intercepte toutes les demandes et ajoute les en-têtes CORS, puis continue avec mes routes normales. Lorsqu'il y a une demande OPTIONS, elle ne répond qu'avec les en-têtes CORS.

EDIT: J'utilisais ce correctif pour deux serveurs nodejs express distincts sur le même ordinateur. En fin de compte, j'ai résolu le problème avec un simple serveur proxy. 

6
Luke Kroon

Je viens de rencontrer ce problème moi-même, dans le contexte d'ASP.NET, assurez-vous que votre Web.config ressemble à ceci: 

  <system.webServer>
<modules>
  <remove name="FormsAuthentication" />
</modules>

<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <!--<remove name="OPTIONSVerbHandler"/>-->
  <remove name="TRACEVerbHandler" />
  <!--
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  -->
</handlers>

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type, Authorization" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
  </customHeaders>
</httpProtocol>

Notez la valeur d'autorisation pour la clé Access-Control-Allow-Headers. Il me manquait la valeur d'autorisation, cette configuration résout mon problème. 

5
Josh Siegl

Très bon je l'ai utilisé sur un projet silex

$app->after(function (Request $request, Response $response) {
        $response->headers->set('Access-Control-Allow-Origin', '*');
        $response->headers->set("Access-Control-Allow-Credentials", "true");
        $response->headers->set("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
        $response->headers->set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
    });
5
Al Kativo

En Chrome:

Le champ d'en-tête de demande X-Requested-With n'est pas autorisé par Access-Control-Allow-Headers dans la réponse de contrôle en amont.

Pour moi, cette erreur a été déclenchée par un espace de fin dans l'URL de cet appel.

jQuery.getJSON( url, function( response, status, xhr ) {
   ...
}
3
user3248255

Juste pour ajouter que vous pouvez également mettre ces en-têtes dans le fichier de configuration Webpack. J'avais besoin d'eux comme dans mon cas car j'utilisais Webpack dev server.

devServer: {
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Credentials": "true",
      "Access-Control-Allow-Methods": "GET,HEAD,OPTIONS,POST,PUT",
      "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept, Authorization"
},
2
Janne

ce problème se produit lorsque nous créons un en-tête personnalisé pour request.Cette demande qui utilise le HTTP OPTIONS et inclut plusieurs en-têtes.

L'en-tête requis pour cette demande estAccess-Control-Request-Headers, qui devrait faire partie de l'en-tête de la réponse et devrait autoriser la demande de toute l'origine. Parfois, il faut aussi Content-Type dans l'en-tête de la réponse. Donc, votre en-tête de réponse devrait être comme ça -

 response.header("Access-Control-Allow-Origin", "*"); // allow request from all Origin
  response.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
  response.header("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin, X-Requested-With, Content-Type, Accept, Authorization");
2
Sai prateek

res.setHeader ('Access-Control-Allow-Headers', '*');

2
KANOMDOOK

Après avoir passé presque une journée, je viens de découvrir que l’ajout des deux codes ci-dessous a résolu mon problème.

Ajoutez ceci dans le Global.asax

  protected void Application_BeginRequest()
    {
        if (Request.HttpMethod == "OPTIONS")
        {
            Response.StatusCode = (int)System.Net.HttpStatusCode.OK;             
            Response.End();
        }
    }

et dans la configuration Web, ajoutez ce qui suit 

 <httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />        
    <add name="Access-Control-Allow-Methods" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type, Authorization" />
  </customHeaders>

</httpProtocol>
1
Biruk Belihu

J'ai reçu l'erreur mentionnée par l'OP avec Django, React et les librairies Django-cors-headers. Pour le réparer avec cette pile, procédez comme suit:

Dans settings.py, ajoutez ce qui suit sous la documentation officielle .

from corsheaders.defaults import default_headers

CORS_ALLOW_HEADERS = default_headers + (
'YOUR_HEADER_NAME',
)
1
Eric

Dans l'appel post API, nous envoyons des données dans le corps de la demande. Donc, si nous allons envoyer des données en ajoutant un en-tête supplémentaire à un appel API. Ensuite, le premier appel API OPTIONS aura lieu, puis un appel ultérieur. Par conséquent, vous devez d'abord gérer l'appel API OPTION.

Vous pouvez gérer le problème en écrivant un filtre et dans lequel vous devez vérifier l'appel de l'API d'appel d'option et renvoyer l'état 200 OK. Voici l'exemple de code:

package com.web.filter;

import Java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.Apache.catalina.connector.Response;

public class CustomFilter implements Filter {
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest httpRequest = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type");
        if (httpRequest.getMethod().equalsIgnoreCase("OPTIONS")) {
            response.setStatus(Response.SC_OK);
        }
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {
        // TODO
    }

    public void destroy() {
        // Todo
    }

}
1
user11815301

Moi aussi, j'ai fait face au même problème dans Angular 6. J'ai résolu le problème en utilisant le code ci-dessous.

Add the code in component.ts file.

    import { HttpHeaders } from '@angular/common/http';

    headers;

    constructor() {
        this.headers = new HttpHeaders();
        this.headers.append('Access-Control-Allow-Headers', 'Authorization');
    }

    getData() {
        this.http.get(url,this.headers). subscribe (res => {
    your code here...

    })

}
0
Karthi Coimbatore

Ce même problème auquel je faisais face.

J'ai fait un changement simple.

  <modulename>.config(function($httpProvider){
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
});
0
Shashikant Pandit

Le message indique clairement que l'autorisation n'est pas autorisée dans l'API. Ensemble
Access-Control-Allow-Headers: "Type de contenu, autorisation"

0
Rajesh Yadav