CORS - Come si esegue il "preflight" di una richiesta http?


94

Sto cercando di effettuare una richiesta HTTP tra domini al servizio WCF (di mia proprietà). Ho letto diverse tecniche per lavorare con le limitazioni dello scripting interdominio. Poiché il mio servizio deve soddisfare sia le richieste GET che POST, non posso implementare alcun tag di script dinamico il cui src è l'URL di una richiesta GET. Dato che sono libero di apportare modifiche al server, ho iniziato a provare a implementare una soluzione alternativa che implica la configurazione delle risposte del server per includere l'intestazione "Access-Control-Allow-Origin" e le richieste di "preflight" con e OPTIONS. Ho avuto l'idea da questo post: far funzionare CORS

Sul lato server, il mio metodo web aggiunge "Access-Control-Allow-Origin: *" alla risposta HTTP. Vedo che le risposte ora includono questa intestazione. La mia domanda è: come faccio a eseguire il "preflight" di una richiesta (OPZIONI)? Sto usando jQuery.getJSON per effettuare la richiesta GET ma il browser annulla immediatamente la richiesta con il famigerato:

L'origine http: // localhost non è consentita da Access-Control-Allow-Origin

Qualcuno ha familiarità con questa tecnica CORS? Quali modifiche devono essere apportate al client per eseguire il preflight della mia richiesta?

Grazie!

Risposte:


158

Durante la richiesta di verifica preliminare, dovresti vedere le seguenti due intestazioni: Metodo di richiesta controllo accesso e Intestazioni richiesta controllo accesso. Queste intestazioni di richiesta chiedono al server le autorizzazioni per effettuare la richiesta effettiva. La risposta del preflight deve riconoscere queste intestazioni affinché la richiesta effettiva funzioni.

Ad esempio, supponiamo che il browser effettui una richiesta con le seguenti intestazioni:

Origin: http://yourdomain.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Custom-Header

Il tuo server dovrebbe quindi rispondere con le seguenti intestazioni:

Access-Control-Allow-Origin: http://yourdomain.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: X-Custom-Header

Presta particolare attenzione all'intestazione di risposta Access-Control-Allow-Headers. Il valore di questa intestazione dovrebbe essere le stesse intestazioni nell'intestazione della richiesta Access-Control-Request-Headers e non può essere "*".

Dopo aver inviato questa risposta alla richiesta di verifica preliminare, il browser effettuerà la richiesta effettiva. Puoi saperne di più su CORS qui: http://www.html5rocks.com/en/tutorials/cors/


potresti aggiungere più domini a Access-Control-Allow-Origin?
botbot

@botbot Probabilmente l'hai già risolto, ma nel caso in cui altri si stiano chiedendo può farloAccess-Control-Allow-Origin: *
Steve Chambers,

2
Forse mi sono perso qualcosa. Quindi dovrei inviare due richieste XMLHttp? Uno per il preflight; controllare la risposta in caso di successo e quindi inviare la query effettiva?
Kangkan

14
@Kangkan non devi preoccuparti di inviare la richiesta di verifica preliminare. Se la richiesta necessita di una verifica preliminare, il browser la invierà per te.
monsur

4
GRAZIE per il bit "presta particolare attenzione" ... che ha risolto il mio problema con node / expressjs Sono stato in grado di aggiungere un filtro per catturare queste richieste di preflight//cors and preflight filtering app.all('*', function(req, res, next){.. //preflight needs to return exact request-header res.set('Access-Control-Allow-Headers', req.headers['access-control-request-headers']); if ('OPTIONS' == req.method) return res.send(204);next(); });
Kurtfm

0

Sebbene questo thread risalga al 2014, il problema può ancora essere attuale per molti di noi. Ecco come l'ho affrontato in un contesto jQuery 1.12 / PHP 5.6:

  • jQuery ha inviato la sua richiesta XHR utilizzando solo intestazioni limitate; è stato inviato solo "Origin".
  • Non è stata necessaria alcuna richiesta di verifica preliminare.
  • Il server doveva solo rilevare tale richiesta e aggiungere "Access-Control-Allow-Origin:". $ _SERVER ['HTTP_ORIGIN'], dopo aver rilevato che si trattava di un XHR cross-origin.

Esempio di codice PHP:

if (!empty($_SERVER['HTTP_ORIGIN'])) {
    // Uh oh, this XHR comes from outer space...
    // Use this opportunity to filter out referers that shouldn't be allowed to see this request
    if (!preg_match('@\.partner\.domain\.net$@'))
        die("End of the road if you're not my business partner.");

    // otherwise oblige
    header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
}
else {
    // local request, no need to send a specific header for CORS
}

In particolare, non aggiungere un exit;preflight poiché non è necessaria alcuna verifica preliminare.

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.