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.

Relaterte artikler