El campo de encabezado de solicitud Access-Control-Allow-Headers no está permitido por Access-Control-Allow-Headers

224

Estoy tratando de enviar archivos a mi servidor con una solicitud de publicación, pero cuando se envía provoca el error:

El campo de encabezado de solicitud Content-Type no está permitido por Access-Control-Allow-Headers.

Así que busqué en Google el error y agregué los encabezados:

$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"
}

Entonces me sale el error:

El campo de encabezado de solicitud Access-Control-Allow-Origin no está permitido por Access-Control-Allow-Headers

Así que busqué en Google y la única pregunta similar que pude encontrar fue proporcionar una media respuesta y luego cerrarla como fuera de tema. ¿Qué encabezados se supone que debo agregar / eliminar?

usuario3194367
fuente
Estos encabezados se envían del servidor al navegador para que el navegador pueda decidir si el JS puede analizar la respuesta. Agregarlos a la solicitud no tiene valor.
pellyadolfo

Respuestas:

189

El servidor (al que se envía la solicitud POST) debe incluir el Access-Control-Allow-Headersencabezado (etc.) en su respuesta . Ponerlos en su solicitud del cliente no tiene ningún efecto.

Esto se debe a que depende del servidor especificar que acepta solicitudes de origen cruzado (y que permite el Content-Typeencabezado de la solicitud, etc.): el cliente no puede decidir por sí mismo que un servidor determinado debe permitir CORS.

Shai
fuente
55
¿Cómo configuro los encabezados en el backend?
user3194367
11
@ user3194367: depende de tu backend.
Felix Kling
15
Supongo que tendré que hablar con mi servidor.
user3194367
2
response.addHeader ("Access-Control-Allow-Headers", "yourKey");
Mayuresh
2
@Mayuresh yourKey es qué? Content-Type?
zhuguowei
240

Yo tuve el mismo problema. En la documentación de jQuery encontré:

Para las solicitudes de varios dominios, fijando el tipo de contenido para que no sea nada application/x-www-form-urlencoded, multipart/form-datao text/plainactivará el navegador para enviar Opciones de comprobación previa petición al servidor.

Entonces, aunque el servidor permite la solicitud de origen cruzado pero no lo permite Access-Control-Allow-Headers, arrojará errores. Por defecto, el tipo de contenido angular es application/json, que está intentando enviar una solicitud de OPCIÓN. Intente sobrescribir el encabezado angular predeterminado o permita el Access-Control-Allow-Headersfinal del servidor. Aquí hay una muestra angular:

$http.post(url, data, {
    headers : {
        'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
    }
});
Pescador
fuente
28
¡Esta debería ser una respuesta aceptada, mucho más informativa que la otra!
Mike Szyndel
1
Quisiera datos multiparte / formulario porque quiero subir algo
Vlado Pandžić
3
or allow Access-Control-Allow-Headers in server end¿cómo?
Omar
1
@omar depende de qué plataforma de servidor esté utilizando. si java hay un ejemplo en otras respuestas si php, entonces hay un nombre de función headerpara establecer el encabezado de la respuesta
Fisherman
1
Finalmente, después de dos días de investigación. ¡No tengo palabras para agradecerte!
Mekey Salaria
51

Si eso ayuda a alguien, (incluso si esto es un poco pobre, ya que solo debemos permitir esto para fines de desarrollo) aquí hay una solución Java ya que encontré el mismo problema. [Editar] No use el comodín * ya que es una mala solución, úsela localhostsi realmente necesita que algo funcione localmente.

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
fuente
Como lo demuestran múltiples respuestas para los encabezados de solicitud de control de acceso, existen claramente diferencias debido a los diferentes entornos. Lo que funcionó para mí fue obtener acceso al objeto de solicitud y volcar los valores para los encabezados, pero específicamente el valor del encabezado para "Access-Control-Request-Headers". Luego, copie / pegue esto en su response.setHeader ("Access-Control-Allow-Headers", "{pegue aquí}"); También estoy usando Java, pero requería valores adicionales y algunos mencionados en esta respuesta no los necesitaba.
Profetas de software
Esta fue una solución parcial (y como se dijo, pobre) para ayudar a las personas y compartir pistas hace un año. No veo el punto de la votación negativa, pero esta es tu libertad. La idea es permitir los encabezados en el lado del servidor para que cuando se publique una solicitud de OPCIÓN, el cliente / navegador sepa qué encabezados están permitidos. Reconozco que hay un poco de confusión, mi filtro CORS ha cambiado mucho desde entonces. Como práctica recomendada, Access-Control-Allow-Origin nunca debería ser *; en mi implementación, lo establece una propiedad.
lekant
La solución ha sido editada para incluir las mejores prácticas
lekant
16

El servidor (al que se envía la solicitud POST) debe incluir el tipo de contenido encabezado en su respuesta.

Aquí hay una lista de encabezados típicos para incluir, incluido un encabezado personalizado "X_ACCESS_TOKEN":

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

Eso es lo que su servidor HTTP necesita configurar para el servidor web al que envía sus solicitudes.

También puede pedirle a su servidor que exponga el encabezado "Content-Length".

Reconocerá esto como una solicitud de Intercambio de recursos de origen cruzado (CORS) y debería comprender las implicaciones de hacer esas configuraciones de servidor.

Para más detalles ver:

l3x
fuente
13

Puede activar el encabezado adecuado en PHP con esto:

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
fuente
44
Describa cómo su respuesta es diferente a las otras respuestas. Solo publicar un código no es muy útil.
oscfri
1
Eres una estrella de rock, el resto de las respuestas profundizan en el aspecto técnico. ¡El tuyo soluciona mi problema al especificar los métodos que también deberían permitirse!
Daniel ZA
1
@DanielZA, aunque entiendo lo que quieres decir con "las otras respuestas profundizan en el lado técnico", ya que solo quieres que tu código se ejecute, SO está destinado a profundizar en el lado técnico de las cosas, ya que debes saber por qué las cosas funcionan no solo cómo hacer que luego funcione. No codifique este comportamiento al comentar soluciones ...
nicolasassi
8

Lo siguiente funciona para mí con 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
fuente
¿Importa el orden de Access-Control-Allow-Methods?
vini
@vini, creo que no importa.
Codificación Ninja
4

Los encabezados que intenta establecer son encabezados de respuesta . Deben ser proporcionados, en la respuesta, por el servidor al que realiza la solicitud.

No tienen lugar establecido en el cliente. No tendría sentido tener un medio para otorgar permisos si pudieran ser otorgados por el sitio que quería permiso en lugar del sitio que poseía los datos.

Quentin
fuente
¿Cómo configuro los encabezados en el backend?
user3194367
@ user3194367 - Depende de tu backend. No sé a qué servidor HTTP o lenguaje de programación está haciendo la solicitud.
Quentin
Supongo que tendré que hablar con mi servidor.
user3194367
3

Si alguien experimenta este problema con un servidor express, agregue el siguiente middleware

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

si prueba algunas solicitudes de JavaScript para ionic2 o angularjs 2, en su Chrome para PC o Mac, asegúrese de instalar el complemento CORS para el navegador Chrome para permitir el origen cruzado.

mayba obtener solicitudes funcionará sin necesidad de eso, pero publicar y poner y eliminar necesitará que instale el complemento cors para que las pruebas funcionen sin problemas, eso definitivamente no es genial, pero no sé cómo lo hacen las personas sin el complemento CORS.

y también asegúrese de que la respuesta json no devuelve 400 por algún estado json

albaiti
fuente
3

Este es un problema de fondo. si usa Sails api en el backend, cambie cors.js y agregue su archivo aquí

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
fuente
3

En Asp Net Core , para que funcione rápidamente para el desarrollo; en Startup.cs, Configure methodagregar

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

En mi caso, recibo varios parámetros como @HeaderParam en un método de servicio web.

Estos parámetros DEBEN declararse en su filtro CORS de esa manera:

@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
fuente
2

Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headerserror significa que el Access-Control-Allow-Origincampo del encabezado HTTP no es manejado o permitido por la respuesta. Eliminar Access-Control-Allow-Origincampo del encabezado de la solicitud.

Tony Stark
fuente
2

Si está utilizando localhosty PHP está configurado para resolver el problema:

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

De su uso frontal:

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

y boom no más problemas de localhost!

jerryurenaa
fuente