Es mēģinu iegūt dažus datus no HP Alm REST API. Tas darbojas diezgan labi ar nelielu curl skriptu - es saņemu savus datus.
Tagad, izmantojot JavaScript, fetch un ES6 (vairāk vai mazāk), šķiet, ir lielāka problēma. Es turpinu saņemt šādu kļūdas ziņojumu:
Fetch API nevar ielādēt
. Atbilde uz preflight pieprasījumu nav't neiztur piekļuves kontroles pārbaudi: Nav 'Access-Control-Allow-Origin' galvenes. pieprasītajam resursam nav. Izcelsme 'http://127.0.0.1:3000' ir tāpēc piekļuve nav atļauta. Atbildes HTTP statusa kods ir 501. Ja jūsu vajadzībām ir nepieciešama necaurspīdīga atbilde, iestatiet pieprasījuma režīmu uz 'no-cors', lai iegūtu resursu ar atslēgtu CORS.
Es saprotu, ka tas ir tāpēc, ka es mēģinu iegūt šos datus no sava lokālā hosta, un risinājumam būtu jāizmanto CORS. Tagad es domāju, ka es to tiešām esmu izdarījis, bet kaut kā tas vai nu ignorē to, ko es ierakstu galvenē, vai problēma ir kaut kur citur?
Tātad, vai ir īstenošanas problēma? Vai es to daru nepareizi? Diemžēl es nevaru pārbaudīt servera žurnālus. Es tiešām esmu nedaudz iestrēdzis.
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));
}
Es izmantoju Chrome. Es arī mēģināju izmantot šo Chrome CORS spraudni, bet tad es saņemu citu kļūdas ziņojumu:
Atbildes galvenes 'Access-Control-Allow-Origin' vērtība nav norādīta. nedrīkst būt aizstājējzīme '*', ja pieprasījuma'pilnvaru režīms ir 'include'. Tādēļ nav atļauts izmantot izcelsmi 'http://127.0.0.1:3000'. piekļuve. Pilnvaru režīms pieprasījumiem, kurus iniciē XMLHttpRequest, kontrolē atribūts withCredentials.
Šī atbilde aptver daudz jautājumu, tāpēc tā ir sadalīta trīs daļās:
Kā izmantot CORS starpniekserveri, lai apietu "Access-Control-Allow-Origin header " problēmas
Ja nekontrolējat serveri, uz kuru jūsu frontend JavaScript kods sūta pieprasījumu, un problēma ar šā servera atbildi ir tikai nepieciešamās Access-Control-Allow-Origin
galvenes trūkums, jūs joprojām varat panākt, lai viss darbotos, veicot pieprasījumu ar CORS starpniekservera palīdzību. Lai parādītu, kā tas darbojas, vispirms šeit ir parādīts kods, kurā nav izmantots CORS starpniekserveris:
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?"))
Iemesls, kādēļ catch
bloks tur tiek aizskarts, ir tāds, ka pārlūkprogramma neļauj šim kodam piekļūt atbildei, kas nāk atpakaļ no https://example.com
. Pārlūkprogramma to dara tāpēc, ka atbildē nav Access-Control-Allow-Origin
atbildes galvenes.
Tagad šeit ir tieši tāds pats piemērs, bet tikai ar pievienotu CORS starpniekserveri:
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?"))
Piezīme: Ja https
https://example.com
.https://example.com
.Access-Control-Allow-Origin
galveni.Access-Control-Allow-Origin
atbildes galveni.
Jūs varat viegli palaist savu proxy, izmantojot kodu no https://github.com/Rob--W/cors-anywhere/.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
, pievienojiet prefiksu savas instances URL, piemēram, https://cryptic-headland-94862.herokuapp.com/https://example.com.
Tāpēc, ja, mēģinot izmantot httpsOPTIONS
pieprasījumu, jo tādā gadījumā starpniekserveris arī nosūta atpakaļ Access-Control-Allow-Headers
un Access-Control-Allow-Methods
galvenes, kas vajadzīgas, lai priekšapstrāde būtu veiksmīga.Kā izvairīties no CORS preflight
Jautājumā minētais kods izraisa CORS preflight, jo tas sūta Authorization
galveni.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
Pat bez tā Content-Type: application/json
galvene arī izraisītu priekšapstrādi.
Pirms pārlūkprogramma izmēģina jautājumā minētajā kodā norādīto POST
, tā vispirms nosūta OPTIONS
pieprasījumu serverim, lai noteiktu, vai serveris piekrīt saņemt pārrobežu POST
, kas ietver Authorization
un Content-Type: application/json
galvenes.
Tas darbojas diezgan labi ar nelielu curl skriptu - es saņemu savus datus. Lai pareizi testētu ar
curl
, jums ir jāemulē pārlūkprogrammas sūtītais priekšizvēlesOPTIONS
pieprasījums:
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"
...ar https://the.sign_in.url
, aizstājot to ar jebkuru jūsu faktisko sign_in
URL.
Atbildē, kas pārlūkprogrammai jāsaņem no šī OPTIONS
pieprasījuma, jāiekļauj šādas galvenes:
Access-Control-Allow-Origin: http://127.0.0.1:3000
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type, Authorization
Ja OPTIONS
atbildē nebūs šo galvenes, pārlūkprogramma apstāsies uz vietas un nekad nemēģinās nosūtīt POST
pieprasījumu. Arī atbildes HTTP statusa kodam jābūt 2xx - parasti 200 vai 204. Ja tas būs jebkurš cits statusa kods, pārlūkprogramma apstāsies uz vietas.
Jautājumā minētais serveris atbild uz OPTIONS
pieprasījumu ar 501 statusa kodu, kas acīmredzot nozīmē, ka tas mēģina norādīt, ka tas neatbalsta OPTIONS
pieprasījumus. Citi serveri šajā gadījumā parasti atbild ar statusa kodu 405 "Metode nav atļauta".
Tātad jūs nekad nevarēsiet veikt POST
pieprasījumus tieši uz šo serveri no sava priekšējā JavaScript koda, ja serveris atbildēs uz šo OPTIONS
pieprasījumu ar 405 vai 501, vai ar jebkuru citu kodu, kas nav 200 vai 204, vai ja neatbildēs ar šīm nepieciešamajām atbildes galvenēm.
Jautājumā minētajā gadījumā varētu izvairīties no priekšapstrādes aktivizēšanas šādi:
Authorization
pieprasījuma galveni, bet tā vietā (piemēram) paļaujas uz autentifikācijas datiem, kas iestrādāti POST
pieprasījuma ķermenī vai kā vaicājuma parametrs.POST
ķermenī būtu Content-Type: application/json
multivides tips, bet tā vietā pieņēma POST
ķermeni kā application/x-www-form-urlencoded
ar parametru ar nosaukumu json
(vai citu), kura vērtība ir JSON datiKā novērst "Access-Control-Allow-Origin header nedrīkst būt aizstājējzīme " problēmas
Es saņemu citu kļūdas ziņojumu:
Atbildes galvenes 'Access-Control-Allow-Origin' vērtība ir 'Access-Control-Allow-Origin'. nedrīkst būt aizstājējzīme '', ja pieprasījuma'pilnvaru režīms ir 'include'. Tādēļ nav atļauts izmantot izcelsmi 'http://127.0.0.1:3000'. piekļuve. Pilnvaru režīms pieprasījumiem, kurus iniciē XMLHttpRequest kontrolē atribūts withCredentials. Pieprasījumam, kas ietver akreditācijas datus, pārlūkprogrammas neļaus jūsu frontend JavaScript kodam piekļūt atbildei, ja atbildes galvenes
Access-Control-Allow-Origin
vērtība ir `. Tā vietā šajā gadījumā vērtībai precīzi jāatbilst jūsu priekšējā koda izcelsmei
http://127.0.0.1:3000. Skatiet [*Pieprasījumi ar atļaujām un aizstājējzīmes*][1] MDN HTTP piekļuves kontroles (CORS) rakstā. Ja jūs kontrolējat serveri, uz kuru sūtāt pieprasījumu, tad parasts veids, kā risināt šo gadījumu, ir konfigurēt serveri tā, lai tas ņemtu
Originpieprasījuma galvenes vērtību un to atbalsotu/atspoguļotu atpakaļ
Access-Control-Allow-Origin` atbildes galvenes vērtībā. Piemēram, izmantojot nginx:
add_header Access-Control-Allow-Origin $http_origin
Es izmantoju Chrome. Es arī mēģināju izmantot šo Chrome CORS spraudni Šis Chrome CORS spraudnis acīmredzot vienkārši un vienkārši injicē
Access-Control-Allow-Origin: *
galveni atbildē, ko redz pārlūkprogramma. Ja šis spraudnis būtu gudrāks, tas iestatītu šīs viltotāsAccess-Control-Allow-Origin
atbildes galvenes vērtību uz jūsu frontend JavaScript koda faktisko izcelsmi -http://127.0.0.1:3000
. Tāpēc izvairieties no šī spraudņa lietošanas pat testēšanai. Tas tikai novērš uzmanību. Ja vēlaties pārbaudīt, kādas atbildes saņemat no servera bez pārlūkprogrammas filtrēšanas, labāk izmantojietcurl -H
, kā norādīts iepriekš.Kas attiecas uz jautājumā minēto priekšējā JavaScript kodu
fetch(...)
pieprasījumam:
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
Noņemiet šīs rindiņas. Access-Control-Allow-*
galvenes ir atbilžu galvenes. Jūs nekad nevēlaties tos sūtīt pieprasījumā. Vienīgais efekts, ko tas radīs, būs tas, ka pārlūkprogramma veiks iepriekšēju pārbaudi.
Šī kļūda rodas, ja klienta URL un servera URL nesakrīt, ieskaitot porta numuru. Šādā gadījumā ir jāaktivizē pakalpojuma CORS, kas ir pārrobežu izcelsmes resursu koplietošana.
Ja jūs mitināt Spring REST pakalpojumu, tad to varat atrast bloga ierakstā CORS atbalsts Spring Framework.
Ja jūs mitināt pakalpojumu, izmantojot Node.js serveri, tad
Apstādiniet Node.js serveri.
npm install cors --save
.
Pievienojiet server.js šādas rindas
var cors = require('cors')
app.use(cors()) // Izmantojiet to pēc mainīgā deklarācijas