Na zahtevanem viru ni glave 'Access-Control-Allow-Origin' - ko poskušate pridobiti podatke iz vmesnika API REST
Poskušam pridobiti nekaj podatkov iz API REST podjetja HP Alm. Z majhno skripto curl deluje dokaj dobro - dobim svoje podatke.
Zdaj pa se zdi, da je to z JavaScript, fetch in ES6 (bolj ali manj) večja težava. Vedno znova dobim to sporočilo o napaki:
Fetch API ne more naložiti . Odziv na zahtevo za predizpolnitev ni
ne prestane preverjanja kontrole dostopa: Ni 'Access-Control-Allow-Origin' glave prisotna na zahtevanem viru. Izvor 'http://127.0.0.1:3000' je zato dostop ni dovoljen. Odgovor je imel kodo stanja HTTP 501. Če nepregleden odgovor ustreza vašim potrebam, nastavite način zahteve na 'no-cors' za pridobitev vira z onemogočenim CORS.
Razumem, da je to zato, ker poskušam te podatke pridobiti iz svojega lokalnega gostitelja in bi morala biti rešitev uporaba CORS. Zdaj sem mislil, da sem to dejansko storil, vendar nekako ne upošteva tega, kar sem napisal v glavi, ali pa je težava v čem drugem?
Torej, ali gre za težavo pri izvajanju? Ali to počnem narobe? Na žalost ne morem preveriti dnevnikov strežnika. Tu sem se res malo zataknil.
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));
}
Uporabljam Chrome. Poskušal sem uporabiti tudi vtičnik CORS za Chrome, vendar sem dobil drugo sporočilo o napaki:
Vrednost glave 'Access-Control-Allow-Origin' v odgovoru
ne sme biti nadomestni znak '*', kadar je način poverilnic zahteve 'include'. Izvor 'http://127.0.0.1:3000' torej ni dovoljen. dostop. Način poverilnic pri zahtevah, ki jih sproži XMLHttpRequest, nadzoruje atribut withCredentials.
Ta odgovor zajema veliko področij, zato je razdeljen na tri dele:
Kako odpraviti težave "Glavička Access-Control-Allow-Origin ne sme biti nadomestni znak "
Kako uporabiti posrednika CORS za izogibanje težavam "Ni glave Access-Control-Allow-Origin " Če nimate nadzora nad strežnikom, ki mu vaša koda JavaScript pošilja zahtevo, in je težava z odgovorom tega strežnika le pomanjkanje potrebne glave
Access-Control-Allow-Origin
, lahko še vedno poskrbite za delovanje tako, da zahtevo pošljete prek posrednika CORS. Da bi pokazali, kako to deluje, najprej predstavljamo nekaj kode, ki ne uporablja posredniškega strežnika CORS:Blok
catch
je tam zadet zato, ker brskalnik preprečuje tej kodi dostop do odgovora, ki se vrne s stranihttps://example.com
. Razlog za to je, da v odgovoru ni glave odgovoraAccess-Control-Allow-Origin
. Tukaj je popolnoma enak primer, vendar z dodanim posrednikom CORS:Pomnilo: Če je https://cors-anywhere.herokuapp.com ob poskusu nedelujoč ali nedostopen, glejte spodaj, kako v samo 2-3 minutah namestite svoj strežnik CORS Anywhere na Heroku. Drugi zgornji del kode lahko uspešno dostopa do odgovora, ker se ob prevzemu URL-ja zahteve in njegovi spremembi v https://cors-anywhere.herokuapp.com/https://example.com-by samo s predpono URL-ja posrednika povzroči, da se zahteva izvede prek tega posrednika, ki nato:
https://example.com
.https://example.com
.Access-Control-Allow-Origin
.Access-Control-Allow-Origin
tisto, kar vidi brskalnik. Z uporabo kode iz https://github.com/Rob--W/cors-anywhere/. Deluje precej dobro z majhno skripto curl - dobim svoje podatke. Za pravilno testiranje zcurl
morate posnemati zahtevoOPTIONS
, ki jo pošlje brskalnik:...z
https://the.sign_in.url
, ki ga zamenja dejanski naslov URL vašegaprijave_in
. Odgovor, ki ga mora brskalnik videti na podlagi te zahteveOPTIONS
, mora vsebovati glave, kot je ta:Če odgovor
OPTIONS
ne vsebuje teh glave, se brskalnik ustavi na tej točki in nikoli ne poskuša poslati zahtevePOST
. Poleg tega mora biti koda stanja HTTP za odgovor 2xx - običajno 200 ali 204. Če je to katera koli druga koda stanja, se brskalnik takoj ustavi. Strežnik v vprašanju se na zahtevoOPTIONS
odzove s kodo stanja 501, kar očitno pomeni, da poskuša sporočiti, da ne izvaja podpore za zahteveOPTIONS
. Drugi strežniki se v tem primeru običajno odzovejo s statusno kodo 405 "Metoda ni dovoljena". Zato nikoli ne boste mogli izvajati zahtevkovPOST
neposredno v ta strežnik iz svoje kode JavaScript v sprednjem delu, če se strežnik na zahtevoOPTIONS
odzove s kodo 405 ali 501 ali kar koli drugega kot 200 ali 204 ali če se ne odzove s temi potrebnimi glavami odgovora. V primeru iz vprašanja bi se izognili sprožitvi predizbrisa na naslednji način:Authorization
, temveč bi se (na primer) zanašal na podatke o avtentikaciji, vgrajene v telo zahtevePOST
ali kot parameter poizvedbeče strežnik ni zahteval, da ima telo
POST
medijsko vrstoContent-Type: application/json
, ampak je namesto tega sprejel teloPOST
kotapplication/x-www-form-urlencoded
s parametromjson
(ali kako drugače), katerega vrednost so podatki JSONKako odpraviti težave "Naslovnica Access-Control-Allow-Origin ne sme biti nadomestni znak "
Vendar je to le en primer; drugi sistemi (spletnih) strežnikov zagotavljajo podobne načine za odmev vrednosti izvora.
Odstranite te vrstice. Glave
Access-Control-Allow-*
so glave odgovora. Nikoli jih ne želite poslati v zahtevi. Edini učinek, ki ga bo to imelo, je ta, da bo brskalnik sprožil predhodno preverjanje.Ta napaka se pojavi, če se URL odjemalca in URL strežnika ne ujemata, vključno s številko vrat. V tem primeru morate svoji storitvi omogočiti CORS, ki je navzkrižna izmenjava virov izvora.
Če gostite storitev Spring REST, jo lahko najdete v objavi na blogu CORS support in Spring Framework.
Če gostite storitev, ki uporablja strežnik Node.js, potem
Ustavite strežnik Node.js.
npm install cors --save
V svoj strežnik.js dodajte naslednje vrstice
var cors = require('cors')
app.use(cors()) // To uporabite po deklaraciji spremenljivke
Odstranite to: