I'm megpróbálok lekérni néhány adatot a HP Alm REST API-jából. Egy kis curl szkripttel elég jól működik - megkapom az adataimat.
A JavaScript, a fetch és az ES6 (többé-kevésbé) nagyobb problémának tűnik. Folyamatosan ezt a hibaüzenetet kapom:
A Fetch API nem tudja betölteni az
nem felel meg a hozzáférés-ellenőrzésnek: Nincs 'Access-Control-Allow-Origin' fejléc. nincs jelen a kért erőforráson. Origin 'http://127.0.0.1:3000' is ezért nem engedélyezett a hozzáférés. A válasz 501-es HTTP státuszkódú volt. Ha egy átláthatatlan válasz szolgálja az Ön igényeit, állítsa a kérés módját a következőre 'no-cors' az erőforrás lekérdezéséhez CORS letiltva.
Értem, hogy ez azért van, mert megpróbálom lehívni ezt az adatot a localhoston belülről, és a megoldásnak CORS-t kellene használnia. Most azt hittem, hogy ezt valóban megtettem, de valahogy vagy figyelmen kívül hagyja, amit a fejlécbe írok, vagy valami más a probléma?
Tehát valami implementációs probléma van? Rosszul csinálom? A szervernaplókat sajnos nem tudom ellenőrizni'ni. Én'tényleg egy kicsit elakadtam itt.
function performSignIn() {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
headers.append('GET', 'POST', 'OPTIONS');
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
fetch(sign_in, {
//mode: 'no-cors',
credentials: 'include',
method: 'POST',
headers: headers
})
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log('Authorization failed : ' + error.message));
}
Chrome-ot használok. Próbáltam használni azt a Chrome CORS Plugint is, de akkor egy másik hibaüzenetet kapok:
A 'Access-Control-Allow-Origin' fejléc értéke a válaszban. nem lehet a vadkártya '*' ha a kérés hitelesítő módszere 'include'. A származási 'http://127.0.0.1:3000' ezért nem megengedett. hozzáférés. A hitelesítő adatok módját a kérések kezdeményezett a XMLHttpRequest által kezdeményezett kéréseket a withCredentials attribútum vezérli.
Ez a válasz sok mindent felölel, ezért három részre oszlik:
Hogyan használjunk CORS proxy-t a "Nincs Access-Control-Allow-Origin fejléc " problémák megkerülésére Ha nem Ön irányítja a szervert, amelyre a frontend JavaScript kódja kérést küld, és a szerver válaszával kapcsolatos probléma csupán a szükséges "Access-Control-Allow-Origin" fejléc hiánya, akkor is megoldható a dolog - a kérés CORS proxy-n keresztül történő végrehajtásával. Hogy megmutassuk, hogyan működik ez, először is itt van néhány olyan kód, amely nem használ CORS proxyt:
const url = "https://example.com"; // site that doesn’t send Access-Control-*
fetch(url)
.then(response => response.text())
.then(contents => console.log(contents))
.catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))
A catch
blokk azért kerül oda, mert a böngésző megakadályozza, hogy ez a kód hozzáférjen a válaszhoz, ami a https://example.com
-ról jön vissza. A böngésző ezt azért teszi, mert a válaszból hiányzik az Access-Control-Allow-Origin
válaszfejléc.
Most pedig itt van pontosan ugyanaz a példa, csak egy CORS proxyval kiegészítve:
const proxyurl = "https://cors-anywhere.herokuapp.com/";
const url = "https://example.com"; // site that doesn’t send Access-Control-*
fetch(proxyurl + url) // https://cors-anywhere.herokuapp.com/https://example.com
.then(response => response.text())
.then(contents => console.log(contents))
.catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))
Figyelem: Ha a https
Access-Control-Allow-Origin
fejlécet.Access-Control-Allow-Origin
válaszfejléccel.
A https://github.com/Rob--W/cors-anywhere/.<br> kód segítségével könnyen futtathatja saját proxyját;
A saját proxy-t is könnyen telepítheted a Heroku-ra, szó szerint mindössze 2-3 perc alatt, 5 paranccsal:git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku master
https://cors-anywhere.herokuapp.com
előtagot írnád, inkább a saját példányod URL-jét írd elé; pl. https://cryptic-headland-94862.herokuapp.com/https://example.com.
Ha tehát, amikor megpróbálja használni a httpsOPTIONS
kérésre készteti - mert ebben az esetben a proxy visszaküldi az Access-Control-Allow-Headers
és Access-Control-Allow-Methods
fejléceket is, amelyek az preflight sikeréhez szükségesek.Hogyan kerüljük el a CORS preflightot
A kérdésben szereplő kód kiváltja a CORS preflightot, mivel Authorization
fejlécet küld.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
E nélkül is a Content-Type: application/json
fejléc kiváltaná az előzetes szűrést.
Az "előfény" jelentése: mielőtt a böngésző megpróbálná a kérdésben szereplő kódban szereplő POST
-ot, először egy OPTIONS
kérést küld a kiszolgálónak - annak megállapítására, hogy a kiszolgáló beleegyezik-e egy olyan cross-origin POST
fogadásába, amely tartalmazza az Authorization
és a Content-Type: application/json
fejlécet.
Ez elég jól működik egy kis curl szkript - megkapom az adataimat. A
curl
megfelelő teszteléséhez emulálnia kell a böngésző által küldött, azOPTIONS
előtti kérést:
curl -i -X OPTIONS -H "Origin: http://127.0.0.1:3000" \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: Content-Type, Authorization' \
"https://the.sign_in.url"
...a https://the.sign_in.url
helyett a tényleges sign_in
URL-t.
A böngésző által az OPTIONS
kérésre kapott válasznak ilyen fejléceket kell tartalmaznia:
Access-Control-Allow-Origin: http://127.0.0.1:3000
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type, Authorization
Ha az OPTIONS
válasz nem tartalmazza ezeket a fejléceket, akkor a böngésző itt megáll, és meg sem próbálja elküldeni a POST
kérést. A válasz HTTP státuszkódjának is 2xx-nek kell lennie - tipikusan 200 vagy 204. Ha ez bármilyen más státuszkód, akkor a böngésző azonnal leáll.
A kérdéses szerver 501-es státuszkóddal válaszol az "OPTIONS" kérésre, ami nyilvánvalóan azt jelenti, hogy nem támogatja az "OPTIONS" kéréseket. Más szerverek ebben az esetben általában 405 "Method not allowed" státuszkóddal válaszolnak.
Tehát soha nem fogsz tudni POST
kéréseket intézni közvetlenül a szerverhez a frontend JavaScript kódodból, ha a szerver 405 vagy 501 vagy bármi mással válaszol az OPTIONS
kérésre, mint 200 vagy 204, vagy ha nem válaszol a szükséges válaszfejlécekkel.
A kérdésben szereplő esetben a következőképpen kerülhetjük el a preflight kiváltását:
Authorization
kérésfejlécet, hanem (például) a POST
kérés testébe vagy lekérdezési paraméterként beágyazott hitelesítési adatokra támaszkodik.POST
testnek Content-Type: application/json
médiatípust kelljen tartalmaznia, hanem a POST
testet application/x-www-form-urlencoded
formátumban fogadja el egy json
(vagy bármi más) nevű paraméterrel, amelynek értéke a JSON adatHogyan lehet megoldani az "Access-Control-Allow-Origin fejléc nem lehet a vadkártya " problémákat
Egy másik hibaüzenetet kapok:
A válaszban szereplő 'Access-Control-Allow-Origin' fejléc értéke nem lehet a joker '', ha a kérés hitelesítő módszere 's 'include'. A származási 'http://127.0.0.1:3000' ezért nem megengedett. hozzáférés. A hitelesítő adatok módját a kérések által kezdeményezett XMLHttpRequest által kezdeményezett kérelmeket a withCredentials attribútum vezérli. A hitelesítő adatokat tartalmazó kérések esetében a böngészők nem engedik, hogy a frontend JavaScript kódja hozzáférjen a válaszhoz, ha az
Access-Control-Allow-Origin
válaszfejléc értéke `. Ehelyett az értéknek ebben az esetben pontosan meg kell egyeznie a frontend kódjának eredetével, a
http://127.0.0.1:3000értékkel. Lásd [*Credentialed requests and wildcards*][1] az MDN HTTP hozzáférés-szabályozás (CORS) című cikkében. Ha Ön irányítja a kiszolgálót, ahová a kérést küldi, akkor az ilyen eset kezelésének gyakori módja, hogy a kiszolgálót úgy konfigurálja, hogy vegye át a
Originkérési fejléc értékét, és azt visszhangozza/tükrözze vissza a
Access-Control-Allow-Origin` válaszfejléc értékébe. Például az nginx-szel:
add_header Access-Control-Allow-Origin $http_origin
Én a Chrome-ot használom. Megpróbáltam a Chrome CORS Plugin használatát is. Az a Chrome CORS plugin nyilvánvalóan csak egyszerűen befecskendez egy
Access-Control-Allow-Origin: *
fejlécet a válaszba, amit a böngésző lát. Ha a plugin okosabb lenne, akkor a hamisAccess-Control-Allow-Origin
válaszfejléc értékét az Ön frontend JavaScript kódjának tényleges eredetére, ahttp://127.0.0.1:3000
értékére állítaná. Kerülje tehát a plugin használatát, még tesztelés céljából is. Csak eltereli a figyelmet. Ha azt akarod tesztelni, hogy milyen válaszokat kapsz a szervertől anélkül, hogy a böngésző szűrné azokat, akkor jobb, ha acurl -H
-t használod, mint fentebb.Ami a kérdésben szereplő
fetch(...)
kérés frontend JavaScript kódját illeti:
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
Távolítsa el ezeket a sorokat. Az Access-Control-Allow-*
fejlécek válasz fejlécek. Soha nem akarod őket kérésben elküldeni. Az egyetlen hatása az, hogy a böngészőt előflightolásra készteti.
Ez a hiba akkor jelentkezik, ha az ügyfél URL és a kiszolgáló URL címe nem egyezik, beleértve a portszámot is. Ebben az esetben engedélyeznie kell a szolgáltatását a CORS, azaz a cross origin resource sharing (kereszt eredetű erőforrás-megosztás) számára.
Ha Spring REST szolgáltatást üzemeltet, akkor ezt a CORS támogatás a Spring Frameworkben blogbejegyzésben találja.
Ha egy Node.js szerverrel rendelkező szolgáltatást hosztolsz, akkor
Állítsa le a Node.js kiszolgálót.
npm install cors --save
.
Adjuk hozzá a következő sorokat a server.js fájlhoz
var cors = require('cors')
app.use(cors()) // Használja ezt a változó deklarációja után
Távolítsa el ezt:
credentials: 'include',