Campo intestazione richiesta Access-Control-Allow-Headers non è consentito da solo nella risposta di verifica preliminare


234

Ho riscontrato più volte i problemi CORS e di solito posso risolverlo, ma voglio davvero capire vedendolo da un paradigma dello stack MEAN.

Prima di aggiungere semplicemente middleware nel mio server express per catturare queste cose, ma sembra che ci sia una sorta di pre-hook che sta rovinando le mie richieste.

Campo di richiesta intestazione Access-Control-Allow-Headers non è consentito da Access-Control-Allow-Headers in risposta al preflight

Supponevo di poter fare questo:

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

o l'equivalente ma questo non sembra risolverlo. Naturalmente ho anche provato

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

Ancora niente fortuna.

Risposte:


245

Quando inizi a giocare con le intestazioni di richiesta personalizzate, otterrai un preflight CORS. Questa è una richiesta che utilizza il OPTIONSverbo HTTP e include diverse intestazioni, una delle quali è l' Access-Control-Request-Headerselenco delle intestazioni che il client desidera includere nella richiesta.

È necessario rispondere a quel preflight CORS con le intestazioni CORS appropriate per farlo funzionare. Uno dei quali è davvero Access-Control-Allow-Headers. Tale intestazione deve contenere gli stessi valori Access-Control-Request-Headerscontenuti nell'intestazione (o più).

https://fetch.spec.whatwg.org/#http-cors-protocol spiega questa configurazione in modo più dettagliato.


41
Se utilizzi Chrome e non sei sicuro di quali intestazioni vengano richieste, utilizza la Console per gli sviluppatori, seleziona la chiamata in rete e puoi visualizzare le intestazioni richieste daAccess-Control-Request-Headers
Lionel Morrison

5
L'opzione Console per gli sviluppatori è buona. Puoi anche trovare ciò di cui hai bisogno ottenendo l'accesso all'oggetto richiesta sul server e scaricando i valori per le intestazioni, ma in particolare il valore dell'intestazione per "Access-Control-Request-Headers". Quindi, copia / incolla questo nel tuo response.setHeader ("Access-Control-Allow-Headers", "{paste here}")
Software Prophets

7
esempio per favore!
Demodave,

5
@Demodave un esempio di questo per me è statoheader("Access-Control-Allow-Headers: Content-Type")
Joshua Duxbury il

1
@LionelMorrison, utilizzo di strumenti di sviluppo Chrome per la corrispondenza delle intestazioni. ben spiegato !!!
Savina Chandla,

119

Questo è ciò che devi aggiungere per farlo funzionare.

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");

Il browser invia una richiesta di verifica preliminare (con il metodo OPTIONS) per verificare se è possibile accedere al servizio ospitato sul server da un browser su un dominio diverso. In risposta alla richiesta di verifica preliminare se si inietta sopra le intestazioni, il browser comprende che è possibile effettuare ulteriori chiamate e riceverò una risposta valida alla mia effettiva chiamata GET / POST. puoi limitare il dominio a cui è concesso l'accesso utilizzando Access-Control-Allow-Origin "," localhost, xvz.com "anziché *. (* garantirà l'accesso a tutti i domini)


7
Non puoi combinare *per ...-Origine trueper ...-Credentials. Non avrà esito negativo per le richieste non accreditate, ma non funzionerà nemmeno per le richieste accreditate. Vedi il link che ho pubblicato nella mia risposta.
Anne,

Grazie Manish Arora, ho usato la tua soluzione nella mia API e ha funzionato. HttpContext.Response.Headers.Add ("Metodi di accesso-controllo-consenti", "OTTIENI, TESTA, OPZIONI, POST, PUT"); HttpContext.Response.Headers.Add ("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method-Access, Access -Controllare-Request-headers "); HttpContext.Response.Headers.Add ("Access-Control-Allow-Origin", " localhost: 4200" );
Ramakrishnankt,

1
Questo sta dicendo che lato server tutta questa munging dell'intestazione di risposta è necessaria a causa di "preflight"? Perché? Soprattutto per intestazioni perfettamente standard? Avendo usato l'HTTP per un po ', è una novità per me che è necessaria così tanta caldaia.
Samantha Atkins,

@manish Avevo un diverso set di valori per Access-Control-Allow-Headers che non funzionava. Il tuo set di valori ha fatto. Grazie per aver risparmiato tempo e frustrazione.
azakgaim,

C'è un modo per jolly alcune intestazioni? È una cattiva idea jolly tutte le intestazioni? Come response.setHeader("Access-Control-Allow-Headers", "*")? Qual è l'implicazione sulla sicurezza di farlo?
Vadorequest,

78

Questo problema è stato risolto

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

Particolare nel mio progetto (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();
});

Aggiornare:

Ogni volta che si verifica un errore: Access-Control-Allow-Headers is not allowed by itself in preflight responseerrore, puoi vedere cosa c'è che non va nello strumento di sviluppo di Chrome :
inserisci qui la descrizione dell'immagine

manca l'errore sopra, Content-Typequindi aggiungi stringa Content-TypeaAccess-Control-Allow-Headers


1
Questo non funzionerà per tutti. Il valore per le intestazioni di richiesta controllo accessi può variare in base all'ambiente. Ottieni l'accesso all'oggetto richiesta sul server e scarica i valori per l'intestazione "Access-Control-Request-Headers". Quindi, copia / incolla questo nel tuo response.setHeader ("Access-Control-Allow-Headers", "{paste here}")
Software Prophets

1
Inoltre, assicurati di scrivere l'autorizzazione in modo americano e non in modo britsh. È mezz'ora della mia vita che non torno indietro. Grazie USA! [sospiro]
geoidesic

14

La risposta accettata è ok, ma ho avuto difficoltà a capirla. Quindi, ecco un semplice esempio per chiarirlo.

Nella mia richiesta Ajax avevo un'intestazione di autorizzazione 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);
}

Questo codice produce l'errore nella domanda. Quello che dovevo fare nel mio server nodejs era aggiungere l'autorizzazione nelle intestazioni consentite:

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

6

Da aggiungere alle altre risposte. Ho avuto lo stesso problema e questo è il codice che ho usato nel mio server express per consentire le chiamate 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();
  }
});

Ciò che questo codice sostanzialmente fa è intercettare tutte le richieste e aggiungere le intestazioni CORS, quindi continuare con i miei percorsi normali. Quando esiste una richiesta OPTIONS, risponde solo con le intestazioni CORS.

EDIT: stavo usando questa correzione per due server espressi nodejs separati sulla stessa macchina. Alla fine ho risolto il problema con un semplice server proxy.


Grazie! Puoi approfondire come hai usato un semplice server proxy?
austin_ce,

5

Mi sono appena imbattuto in questo problema da solo, nel contesto di ASP.NET assicurati che il tuo Web.config assomigli a questo:

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

Notare il valore di autorizzazione per la Access-Control-Allow-Headerschiave. Mi mancava il valore di autorizzazione, questa configurazione risolve il mio problema.


5

Molto bene l'ho usato su un progetto 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");
    });

2
Sebbene questo codice possa rispondere alla domanda, fornire un contesto aggiuntivo riguardo a come e / o perché risolve il problema migliorerebbe il valore a lungo termine della risposta.
Badacadabra,

4

In Chrome:

Il campo di intestazione della richiesta X-Richiesto-Con non è consentito da Access-Control-Allow-Headers in risposta al preflight.

Per me, questo errore è stato innescato da uno spazio finale nell'URL di questa chiamata.

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

3

Solo per aggiungere che puoi inserire quelle intestazioni anche nel file di configurazione di Webpack. Ne avevo bisogno come nel mio caso mentre stavo eseguendo il server dev webpack.

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

Ho ricevuto l'errore dichiarato dall'OP usando Django, React e la libreria django-cors-head. Per risolverlo con questo stack, procedi come segue:

In settings.py aggiungi quanto segue per la documentazione ufficiale .

from corsheaders.defaults import default_headers

CORS_ALLOW_HEADERS = default_headers + (
'YOUR_HEADER_NAME',
)

2

questo problema si verifica quando creiamo un'intestazione personalizzata per la richiesta. Questa richiesta che utilizza le HTTP OPTIONSintestazioni e include diverse intestazioni.

L'intestazione richiesta per questa richiesta è Access-Control-Request-Headers, che dovrebbe far parte dell'intestazione della risposta e dovrebbe consentire la richiesta da tutte le origini. A volte è necessario Content-Typeanche nell'intestazione della risposta. Quindi l'intestazione della risposta dovrebbe essere così:

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");

1

Nella chiamata post API inviamo i dati nel corpo della richiesta. Quindi, se invieremo dati aggiungendo un'intestazione aggiuntiva a una chiamata API. Quindi la prima chiamata API OPTIONS accadrà e poi accadrà la chiamata. Pertanto, è necessario gestire prima la chiamata API OPTION.

È possibile gestire il problema scrivendo un filtro e al suo interno è necessario verificare la chiamata dell'API di chiamata delle opzioni e restituire uno stato 200 OK. Di seguito è riportato il codice di esempio:

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

Se si sta tentando di aggiungere un'intestazione personalizzata nelle intestazioni della richiesta, è necessario comunicare al server che è consentita l'intestazione specifica. Il posto dove farlo è nella classe che filtra le richieste. Nell'esempio mostrato di seguito, il nome dell'intestazione personalizzata è "type":

public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin",  request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,PATCH,OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me, Authorization, type ");
        response.setHeader("Access-Control-Expose-Headers","Authorization");
    }
}

1

Dopo aver trascorso quasi un giorno, ho appena scoperto che l'aggiunta dei due codici seguenti ha risolto il mio problema.

Aggiungi questo nel Global.asax

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

e nella configurazione web aggiungere quanto segue

<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

Anch'io ho affrontato lo stesso problema in Angular 6. Ho risolto il problema utilizzando il codice seguente. Aggiungi il codice nel file component.ts.

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

Lo stesso problema che stavo affrontando.

Ho fatto un semplice cambiamento.

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

0

Il messaggio indica che "Autorizzazione" non è consentita nell'API. Imposta
access-Control-Allow-Headers: "Tipo-contenuto, Autorizzazione"


0
const express = require('express')
const cors = require('cors')
const app = express()

app.get('/with-cors', cors(), (req, res, next) => {
  res.json({ msg: 'WHOAH with CORS it works! 🔝 🎉' })
})

Aggiungere cors alla funzione get È quello che ha funzionato per me

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.