Le champ d'en-tête de demande Access-Control-Allow-Headers n'est pas autorisé par Access-Control-Allow-Headers

224

J'essaie d'envoyer des fichiers à mon serveur avec une demande de publication, mais lorsqu'il envoie, il provoque l'erreur:

Le champ d'en-tête de demande Content-Type n'est pas autorisé par Access-Control-Allow-Headers.

J'ai donc recherché l'erreur sur Google et ajouté les en-têtes:

$http.post($rootScope.URL, {params: arguments}, {headers: {
    "Access-Control-Allow-Origin" : "*",
    "Access-Control-Allow-Methods" : "GET,POST,PUT,DELETE,OPTIONS",
    "Access-Control-Allow-Headers": "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
}

Ensuite, je reçois l'erreur:

Le champ d'en-tête de demande Access-Control-Allow-Origin n'est pas autorisé par Access-Control-Allow-Headers

J'ai donc fait une recherche sur Google et la seule question similaire que j'ai pu trouver a été une demi-réponse, puis fermée comme hors sujet. Quels en-têtes dois-je ajouter / supprimer?

user3194367
la source
Ces en-têtes sont envoyés du serveur au navigateur afin que le navigateur puisse décider si le JS est autorisé à analyser la réponse. Les ajouter à la demande n'a pas de valeur.
pellyadolfo

Réponses:

189

Le serveur (auquel la requête POST est envoyée) doit inclure l'en- Access-Control-Allow-Headerstête (etc.) dans sa réponse . Les mettre dans votre demande du client n'a aucun effet.

En effet, il appartient au serveur de spécifier qu'il accepte les demandes d'origine croisée (et qu'il autorise l'en- Content-Typetête de demande, etc.) - le client ne peut pas décider par lui-même qu'un serveur donné doit autoriser CORS.

Shai
la source
5
Comment définir les en-têtes dans le backend?
user3194367
11
@ user3194367: dépend de votre backend.
Felix Kling
15
Je suppose que je vais devoir parler à mon serveur.
user3194367
2
response.addHeader ("Access-Control-Allow-Headers", "yourKey");
Mayuresh
2
@Mayuresh yourKey c'est quoi? Content-Type?
zhuguowei
240

J'ai eu le même problème. Dans la documentation jQuery, j'ai trouvé:

Pour les demandes inter-domaines, le réglage du type de contenu à autre chose que application/x-www-form-urlencoded, multipart/form-dataou text/plaindéclenchera le navigateur pour envoyer une demande OPTIONS prévol au serveur.

Donc, bien que le serveur autorise la demande d'origine croisée mais ne le permet pas Access-Control-Allow-Headers, il générera des erreurs. Par défaut, le type de contenu angulaire est application/json, qui essaie d'envoyer une demande OPTION. Essayez d'écraser l'en-tête par défaut angulaire ou autorisez Access-Control-Allow-Headersà l'extrémité du serveur. Voici un échantillon angulaire:

$http.post(url, data, {
    headers : {
        'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
    }
});
Pêcheur
la source
28
Cela devrait être une réponse acceptée, beaucoup plus informative que l'autre!
Mike Szyndel
1
Je voudrais multipart / form-data parce que je veux mettre quelque chose en place
Vlado Pandžić
3
or allow Access-Control-Allow-Headers in server endComment?
Omar
1
@omar cela dépend de la plateforme serveur que vous utilisez. si java il y a un exemple sur d'autres réponses si php alors il y a un nom de fonction headerpour définir l'en-tête de la réponse
Fisherman
1
Enfin, après deux jours de recherche. Je n'ai pas de mots pour te remercier!
Mekey Salaria
51

Si cela aide quelqu'un (même si c'est un peu pauvre car nous ne devons le permettre qu'à des fins de développement), voici une solution Java car j'ai rencontré le même problème. [Modifier] N'utilisez pas le caractère générique * car c'est une mauvaise solution, utilisez localhostsi vous avez vraiment besoin que quelque chose fonctionne localement.

public class SimpleCORSFilter implements Filter {

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "my-authorized-proxy-or-domain");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
    chain.doFilter(req, res);
}

public void init(FilterConfig filterConfig) {}

public void destroy() {}

}
lekant
la source
Comme en témoignent les réponses multiples aux en-têtes de demande de contrôle d'accès, il existe clairement des différences dues à des environnements différents. Ce qui a fonctionné pour moi était d'obtenir l'accès à l'objet de demande et de vider les valeurs des en-têtes, mais plus précisément la valeur d'en-tête pour "Access-Control-Request-Headers". Ensuite, copiez / collez ceci dans votre response.setHeader ("Access-Control-Allow-Headers", "{paste here}"); J'utilise aussi Java, mais j'avais besoin de valeurs supplémentaires et certaines mentionnées dans cette réponse, je n'en avais pas besoin.
Software Prophets
Il s'agissait d'une solution partielle (et comme on l'a dit, médiocre) pour aider les gens et partager des indices un an plus tôt. Je ne vois pas l'intérêt de voter contre, mais c'est votre liberté. L'idée est d'autoriser les en-têtes côté serveur, donc lorsqu'une requête OPTION est publiée, le client / le navigateur sait quels en-têtes sont autorisés. Je reconnais qu'il y a un peu de confusion, mon filtre CORS a beaucoup changé depuis lors. Comme meilleure pratique, Access-Control-Allow-Origin ne devrait jamais être *; dans mon implémentation, il est défini par une propriété.
lekant
La solution a été modifiée pour inclure les meilleures pratiques
lekant
16

Le serveur (auquel la demande POST est envoyée) doit inclure l'en - tête Content-Type dans sa réponse.

Voici une liste d'en-têtes typiques à inclure, y compris un en-tête "X_ACCESS_TOKEN" personnalisé:

"X-ACCESS_TOKEN", "Access-Control-Allow-Origin", "Authorization", "Origin", "x-requested-with", "Content-Type", "Content-Range", "Content-Disposition", "Content-Description"

C'est ce que votre serveur http doit configurer pour le serveur Web auquel vous envoyez vos demandes.

Vous pouvez également demander à votre serveur de dévoiler l'en-tête "Content-Length".

Il reconnaîtra cela comme une demande CORS (Cross-Origin Resource Sharing) et devrait comprendre les implications de la configuration de ces serveurs.

Pour plus de détails, voir:

l3x
la source
13

Vous pouvez activer l'en-tête approprié en PHP avec ceci:

header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, X-Requested-With");
Vinod Dhakad
la source
4
Veuillez décrire en quoi votre réponse est différente des autres réponses. Publier du code n'est pas très utile.
oscfri
1
Vous êtes une rock star, le reste des réponses plonge dans le côté technique. Le vôtre corrige mon problème, en spécifiant les méthodes qui devraient également être autorisées!
Daniel ZA
1
@DanielZA bien que je comprenne ce que vous entendez par "les autres réponses plongent dans le côté technique" car vous voulez juste faire fonctionner votre code, SO est censé plonger dans le côté technique des choses comme vous devriez savoir pourquoi les choses fonctionnent non seulement comment faire puis travailler. N'encorez pas ce comportement lorsque vous commentez des solutions ...
nicolasassi
8

Ce qui suit fonctionne pour moi avec nodejs:

xServer.use(function(req, res, next) {
  res.setHeader("Access-Control-Allow-Origin", 'http://localhost:8080');
  res.setHeader('Access-Control-Allow-Methods', 'POST,GET,OPTIONS,PUT,DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Accept');

  next();
});
Fernando Gabrieli
la source
l'ordre des méthodes Access-Control-Allow-Methods est-il important?
vini
@vini, je pense que cela n'a pas d'importance.
Codage Ninja
4

Les en-têtes que vous essayez de définir sont des en- têtes de réponse . Ils doivent être fournis, dans la réponse, par le serveur auquel vous faites la demande.

Ils n'ont pas leur place sur le client. Il serait inutile d'avoir un moyen d'accorder des autorisations si elles pouvaient être accordées par le site qui en demandait l' autorisation plutôt que par le site propriétaire des données.

Quentin
la source
Comment définir les en-têtes dans le backend?
user3194367
@ user3194367 - Cela dépend de votre backend. Je ne sais pas à quel serveur HTTP ou langage de programmation vous faites la demande.
Quentin
Je suppose que je vais devoir parler à mon serveur.
user3194367
3

Si quelqu'un rencontre ce problème avec un serveur express, ajoutez le middleware suivant

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});
realappie
la source
3

si vous testez des requêtes javascript pour ionic2 ou angularjs 2, dans votre chrome sur PC ou Mac, assurez-vous d'installer le plug-in CORS pour le navigateur Chrome pour autoriser l'origine croisée.

mayba get requests fonctionnera sans avoir besoin de cela, mais post and put et delete vous aurez besoin d'installer le plugin cors pour que les tests se passent sans problème, ce n'est certainement pas cool, mais je ne sais pas comment les gens le font sans plugin CORS.

et assurez-vous également que la réponse json ne retourne pas 400 par un certain statut json

albaiti
la source
3

c'est un problème de backend. si vous utilisez l'api des voiles sur le backend, changez cors.js et ajoutez votre fichier ici

module.exports.cors = {
  allRoutes: true,
  origin: '*',
  credentials: true,
  methods: 'GET, POST, PUT, DELETE, OPTIONS, HEAD',
  headers: 'Origin, X-Requested-With, Content-Type, Accept, Engaged-Auth-Token'
};
Sedat Y
la source
3

Dans Asp Net Core , pour le faire fonctionner rapidement pour le développement; dans Startup.cs, Configure methodajoutez

app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
Gabriel P.
la source
2

Dans mon cas, je reçois plusieurs paramètres en tant que @HeaderParam dans une méthode de service Web.

Ces paramètres DOIVENT être déclarés dans votre filtre CORS de cette façon:

@Provider
public class CORSFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {

        MultivaluedMap<String, Object> headers = responseContext.getHeaders();

        headers.add("Access-Control-Allow-Origin", "*");
        ...
        headers.add("Access-Control-Allow-Headers", 
        /*
         * name of the @HeaderParam("name") must be declared here (raw String):
         */
        "name", ...);
        headers.add("Access-Control-Allow-Credentials", "true");
        headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");   
    }
}
Russellhoff
la source
2

Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headerserreur signifie que le Access-Control-Allow-Originchamp de l'en-tête HTTP n'est pas géré ou autorisé par la réponse. Supprimer le Access-Control-Allow-Originchamp de l'en-tête de la demande.

Tony Stark
la source
2

Si vous utilisez localhostPHP et définissez-le pour résoudre le problème:

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Content-Type'); 

De votre utilisation front-end:

{headers: {"Content-Type": "application/json"}}

et boum plus de problèmes localhost!

jerryurenaa
la source