Sto scrivendo un client JavaScript da includere in siti di terze parti (si pensi al pulsante Mi piace di Facebook). È necessario recuperare le informazioni da un'API che richiede l'autenticazione HTTP di base. La configurazione semplificata è simile al seguente:Perché la richiesta OPZIONI di verifica preliminare di una richiesta CORS autenticata funziona in Chrome ma non in Firefox?
Un sito 3rd party include questo frammento sulla loro pagina:
<script
async="true"
id="web-dev-widget"
data-public-key="pUbl1c_ap1k3y"
src="http://web.dev/widget.js">
</script>
widget.js chiama l'API:
var el = document.getElementById('web-dev-widget'),
user = 'token',
pass = el.getAttribute('data-public-key'),
url = 'https://api.dev/',
httpRequest = new XMLHttpRequest(),
handler = function() {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
console.log(httpRequest.responseText);
} else {
console.log('There was a problem with the request.', httpRequest);
}
}
};
httpRequest.open('GET', url, true, user, pass);
httpRequest.onreadystatechange = handler;
httpRequest.withCredentials = true;
httpRequest.send();
L'API è stata configurata per rispondere con intestazioni appropriate:
Header set Access-Control-Allow-Credentials: true
Header set Access-Control-Allow-Methods: "GET, OPTIONS"
Header set Access-Control-Allow-Headers: "origin, authorization, accept"
SetEnvIf Origin "http(s)?://(.+?\.[a-z]{3})$" AccessControlAllowOrigin=$0
Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Si noti che Access-Control-Allow-Origin
è impostato su Origin
invece di utilizzare un carattere jolly perché sto inviando una richiesta con credenziali (withCredentials
).
Ora è tutto pronto per creare una richiesta autenticata da più domini asincroni e funziona perfettamente su Chrome 25 su OS X 10.8.2. In Dev Tools, posso vedere la richiesta di rete per la richiesta OPTIONS
prima della richiesta GET
e la risposta ritorna come previsto.
Quando si verifica in Firefox 19, nessuna richiesta di rete appaiono in Firebug alle API, e questo errore viene registrato nella console: NS_ERROR_DOM_BAD_URI: Access to restricted URI denied
Dopo molte scavo, ho scoperto che Gecko doesn't allow the username and password to be directly in a cross-site URI, secondo le osservazioni. Ho pensato che questo era l'uso del utente e la password opzionale params per open()
così ho provato l'altro metodo di fare le richieste autenticate che è quello di Base64 codificare le credenziali e inviare in un'intestazione Autorizzazione:
// Base64 from http://www.webtoolkit.info/javascript-base64.html
auth = "Basic " + Base64.encode(user + ":" + pass);
...
// after open() and before send()
httpRequest.setRequestHeader('Authorization', auth);
Questo si traduce in un 401 Unauthorized
risposta alla richiesta OPTIONS
che conduce a ricerche di Google come "Perché funziona in Chrome e non in Firefox !?" Fu allora che capii di essere nei guai.
Perché fa funziona in Chrome e non in Firefox? Come posso ottenere la richiesta OPTIONS
per inviare e rispondere in modo coerente?
Mi piacerebbe inserire come rendere la domanda migliore – maxbeatty