javascript - Forespørselsheaderfeltet Access-Control-Allow-Headers er ikke tillatt alene i preflight-svar
Jeg har støtt på CORS-problemer flere ganger og kan vanligvis fikse det, men jeg ønsker virkelig å forstå det ved å se dette fra et MEAN-stack perspektiv.
Tidligere la jeg ganske enkelt til middleware i Express-serveren min for å fange opp disse tingene. Imidlertid ser det ut til at det finnes en slags forhåndskrok som feiler forespørslene mine.
Forespørselsheaderfeltet Access-Control-Allow-Headers er ikke tillatt av Access-Control-Allow-Headers i forflytningsresponsen
Jeg antok at jeg kunne gjøre dette:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Headers","*")
})
eller tilsvarende, men dette ser ikke ut til å løse det. Jeg har selvfølgelig også prøvd
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Headers","Access-Control-Allow-Headers")
})
Fortsatt ikke flaks.
Svar #1
Når du begynner å eksperimentere med tilpassede forespørselsoverskrifter, vil du få en CORS-forhåndsforespørsel. Dette er en forespørsel som bruker HTTP-verb OPTIONS og inkluderer flere overskrifter, en av dem er Access-Control-Request-Headers som viser hvilke overskrifter klienten ønsker å inkludere i forespørselen.
Du må svare på den CORS preflight med de riktige CORS-headerne for å få dette til å fungere. En av dem er faktisk Access-Control-Allow-Headers. Den headeren må inneholde de samme verdiene som Access-Control-Request-Headers headeren inneholdt (eller flere).
https://fetch.spec.whatwg.org/#http-cors-protocol forklarer denne oppsettet i mer detalj.
Svar #2
Dette er det du trenger å legge til for å få det til å fungere.
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");
Nettleseren sender en preflight-forespørsel (med metoden TYPE OPTIONS) for å sjekke om tjenesten som er vert på serveren, har tillatelse til å bli aksessert fra nettleseren på et annet domene. Som svar på preflight-forespørselen, hvis du setter inn de ovennevnte overskriftene, forstår nettleseren at det er greit å gjøre ytterligere kall, og jeg vil få et gyldig svar på min faktiske GET/POST-forespørsel. Du kan begrense domenet som tilgang gis til ved å bruke Access-Control-Allow-Origin, "localhost, xvz.com" i stedet for *. (* vil gi tilgang til alle domener)
Svar #3
Dette problemet løst med
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
Spesielt i prosjektet mitt (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();
});
Oppdatering :
Hver gang feilen: Access-Control-Allow-Headers er ikke tillatt alene i forhåndsrespons kan du se hva som er galt med Chrome utviklerverktøy:
ovennevnte feil mangler Content-Type så legg til strengen Content-Type i Access-Control-Allow-Headers
Svar #4
Det aksepterte svaret er greit, men jeg hadde vanskeligheter med å forstå det. Så her er et enkelt eksempel for å tydeliggjøre det.
I mitt Ajax-forespørsel hadde jeg en standard autorisasjonsheader.
$$(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);
}
Denne koden gir feilen i spørsmålet. Det jeg måtte gjøre på min Node.js-server, var å legge til Authorization i tillatte overskrifter:
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,**Authorization**');
Svar #5
Bare for å legge til at du kan legge de headerne også til Webpack-konfigurasjonsfilen. Jeg trengte dem i mitt tilfelle siden jeg kjørte 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"
}
},
Svar #6
For å legge til de andre svarene. Jeg hadde det samme problemet, og dette er koden jeg brukte i min express-server for å tillate REST-kall:
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();
}
});
Hva denne koden i utgangspunktet gjør er å avskjære alle forespørsler og legge til CORS-overskriftene, og deretter fortsette med mine normale ruter. Når det er en OPTIONS-forespørsel svarer den bare med CORS-overskriftene.
REDIGER: Jeg brukte denne løsningen for to separate Node.js Express-servere på samme maskin. Til slutt løste jeg problemet med en enkel proxy-server.
