2016-02-04 7 views
17

Utilizzo un front-end angular2 e il backend WebApi. Il WebAPI è CORS abilitatoAngular2 a REST WebApi CORS issue

var cors = new EnableCorsAttribute("*", "*", "*"); 
GlobalConfiguration.Configuration.EnableCors(cors); 

e funziona, perché ho diversi siti (jQuery/Javascript) che utilizzano questa API. Ma con angular2 no. Viene visualizzato il seguente messaggio:

La risposta alla richiesta di preflight non supera il controllo del controllo accessi: Nessuna intestazione 'Access-Control-Allow-Origin' è presente sulla risorsa richiesta.

Forse è qualcosa di simile a "richiesta preflight"?

+0

Ho letto i documenti per "Abilitazione di richieste di origine incrociata in API Web ASP.NET" e dovresti avere questa intestazione nella risposta. Vedere la sezione "Come funziona CORS" in questa pagina: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api#how-it-works. –

+1

*** Sto chiudendolo, perché è solo un errore di battitura per OP. *** – Win

+0

penso che questo problema nelle proprietà del server veda: http://stackoverflow.com/questions/36825429/angular-2-no -access-control-allow-origin-header-is-present-on-the-request –

risposta

5

Il messaggio di errore indica che non c'è Access-Control-Allow-Origin nella risposta della chiamata. È qualcosa di necessario per abilitare CORS per questa richiesta. Non è qualcosa correlato a Angular2.

Questo viene attivato dal lato client aggiungendo l'intestazione Origin nella richiesta. Hai questa intestazione nella tua richiesta? Usi le richieste preflight nelle tue altre applicazioni. Come promemoria:

  • Richieste semplici. Questo caso d'uso si applica se utilizziamo i metodi HTTP GET, HEAD e POST. Nel caso dei metodi POST, sono supportati solo i tipi di contenuto con i seguenti valori: text/plain, application/x-www-form-urlencoded e multipart/form-data.
  • Richieste preflight. Quando il caso d'uso "richieste semplici" non si applica, viene effettuata una prima richiesta (con il metodo HTTP OPTIONS) per verificare cosa può essere fatto nel contesto di richieste interdominio.

Forse le richieste di OPZIONI non sono gestite correttamente sul lato server (non restituire intestazioni corrette, ...).

Ciò che sarebbe interessante è dirci su quali richieste si verifica l'errore: l'OPTIONS o la richiesta di destinazione. Si può avere uno sguardo alla schedaRete in DevTools ...

Vedi questi link per maggiori dettagli su come funziona CORS:

spero che ti aiuta, Thierry

+1

+1 Mi ha dato la direzione giusta perché stavo lottando sul client, ma l'errore pre-volo era a causa del blocco del server della richiesta cors con alcune intestazioni.Quindi devo consentire tutte le intestazioni nel mio scenario. – Nexus23

+0

@Thierry Templier puoi dare un'occhiata a questa [domanda] (https://stackoverflow.com/questions/45444625/angular-2-httppost-to-oauth2/45444912?noredirect=1#comment77860961_45444912)? –

1

Avete alcune opzioni impostate nel vostro file web.config per cors? Mi piace qualcosa

Se sì, assicurati di rimuoverlo e controlla il cors solo attraverso il codice.

La risposta here ti aiuterà.

8

Ho avuto lo stesso problema nella mia applicazione Angular2. Il problema, come già detto, è che prima di ogni richiesta effettuata dal cliente viene inviata al server una richiesta di preflight .

Questo tipo di richiesta sono un tipo OPZIONI, ed è dovere del server per inviare una risposta preflight con lo stato 200 e intestazioni fissati per accettare le richieste da quel cliente.

Questa è la mia soluzione (con espresso):

// Domain you wish to allow 
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000'); 

// Request methods you wish to allow 
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE'); 

// Request headers you wish to allow 
res.setHeader('Access-Control-Allow-Headers', 'YOUR-CUSTOM-HEADERS-HERE'); 

// Set to true if you need the website to include cookies in requests 
res.setHeader('Access-Control-Allow-Credentials', true); 

// Check if preflight request 
if (req.method === 'OPTIONS') { 
    res.status(200); 
    res.end(); 
} 
else { 
    // Pass to next layer of middleware 
    next(); 
} 

Come potete vedere, ho impostato le intestazioni e quindi scarica se il tipo di richiesta è OPZIONI. In tal caso, rispedisco uno stato 200 e termino la risposta.

In questo modo, il cliente sarà autorizzato e sarà inoltre possibile impostare le intestazioni personalizzate in tutte le richieste.

+1

Dove hai messo quelle linee? –

+0

Prima della dichiarazione dei percorsi. –

+0

Ha funzionato, grazie. Ho usato [il middleware CORS] (https://www.npmjs.com/package/cors) ma non ha funzionato. Perché? Questo codice non fa la stessa cosa? –

1

So che la domanda non è chiedere codice PHP. Sono arrivato qui a causa di tutta questa faccenda di preflight e Angular2. Quando ho guardato la risposta di Matteo, ho capito perché la richiesta al mio server tornava con 401. Questo perché nel browser di preflight non invia il token di autorizzazione e quindi il server torna con 401 e il browser pensa che CORS non sia consentito . Si prega di essere consapevoli che il codice qui sotto dovrebbe essere utilizzato solo nel server di sviluppo a meno che non si sappia cosa si sta facendo.

In PHP si può fare questo:

if (strtolower($_SERVER['REQUEST_METHOD']) === 'options') { 
     header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']); 
     header('Access-Control-Allow-Methods: POST, GET, OPTIONS'); 
     header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Range, Content-Disposition, Content-Type, Authorization'); 
     header('Access-Control-Allow-Credentials: true'); 
     echo 'Allowed'; 
     exit; 
} 

O Nginx

if ($request_method = 'OPTIONS') { 
     add_header 'Access-Control-Allow-Origin' '*'; 
     add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; 
     # 
     # Custom headers and headers various browsers *should* be OK with but aren't 
     # 
     add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; 
     # 
     # Tell client that this pre-flight info is valid for 20 days 
     # 
     add_header 'Access-Control-Max-Age' 1728000; 
     add_header 'Content-Type' 'text/plain charset=UTF-8'; 
     add_header 'Content-Length' 0; 
     return 204; 
    } 

Ricorda qualsiasi altro intestazioni si sta inviando al server è necessario essere aggiunto ad Access-Control-Allow-Headers elenco.

0

sto lavorando con angolare 2 per il front-end e nodeJS (Expressjs) per l'API

angolare 2 sta lavorando sotto localhost: 3000 e esprimono sta lavorando su localhost: 8000

Il problema succede quando localhost: 3000 tenta di chiamare un URL con il metodo POST ... Il server expressJS rifiuta la chiamata perché proviene da un altro server (o porta)

Per risolvere il problema si deve dire al nodo js di accettare chiamate dal localhost: 3000 server ...

You can find a library (CORS) to avoid this problem in this link: