Bu cevap çok fazla zemini kapsıyor, bu yüzden üç bölüme ayrılıyor:
- "Erişim-Denetim-İzin Verme Başlığı Yok" sorunlarının çözümü için CORS proxy'si nasıl kullanılır
- CORS ön kontrolünden nasıl kaçınılır?
- “Access-Control-Allow-Origin üstbilgisi joker karakter olmamalıdır” sorunları nasıl düzeltilir
"Erişim-Denetim-İzin Verme Başlığı Yok" sorunlarının çözümü için CORS proxy'si nasıl kullanılır
Sunucunuzu kontrol edemiyorsanız, ön uç JavaScript kodunuz bir istek gönderir ve bu sunucudan gelen yanıtla ilgili sorun yalnızca gerekli Access-Control-Allow-Originbaşlığın olmamasıdır , yine de bir şeyler yaparak istekte bulunabilirsiniz. CORS vekili. Bunun nasıl çalıştığını göstermek için, önce CORS proxy'sini kullanmayan bazı kodlar aşağıdadır:
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?"))
catchBloğun vurulmasının nedeni, tarayıcı bu kodun geri gelen yanıta erişmesini engeller https://example.com. Ve tarayıcının bunu yapmasının nedeni, yanıtın Access-Control-Allow-Originyanıt başlığından yoksundur .
Şimdi, tam olarak aynı örnek, ancak yalnızca bir CORS proxy'si eklendi:
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?"))
Not: https://cors-anywhere.herokuapp.com denediğinizde kullanılamıyor veya kullanılamıyorsa, Heroku'da kendi CORS Anywhere sunucunuzu sadece 2-3 dakikada nasıl dağıtacağınız için aşağıya bakın.
Yukarıdaki ikinci kod snippet'i, istek URL'sini alıp https://cors-anywhere.herokuapp.com/https://example.com ( yalnızca proxy URL'sinin önüne ekleyerek) olarak değiştirerek yanıta başarıyla erişebilir . o proxy üzerinden yapılma talebi, daha sonra:
- İsteği adresine yönlendirir
https://example.com.
- Adlı kullanıcıdan yanıt alır
https://example.com.
Access-Control-Allow-OriginYanıtı yanıta ekler .
- Bu yanıtı, eklenen üstbilgiyle, istekte bulunan ön uç koduna geri gönderir.
Daha sonra tarayıcı, ön uç kodunun yanıta erişmesine izin verir, çünkü Access-Control-Allow-Originyanıt üstbilgisiyle bu yanıt tarayıcının gördüğü şeydir.
Https://github.com/Rob--W/cors-anywhere/ adresindeki kodu kullanarak kendi proxy'nizi kolayca çalıştırabilirsiniz .
5 komutla kelimenin tam anlamıyla 2-3 dakikada kendi proxy'nizi kolayca Heroku'ya dağıtabilirsiniz:
git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku master
Bu komutları çalıştırdıktan sonra, kendi https://cryptic-headland-94862.herokuapp.com/ adresinde çalışan kendi CORS Anywhere sunucunuz olur . Bu durumda, istek URL'nize önek eklemek https://cors-anywhere.herokuapp.comyerine, kendi örneğinizin URL'sine önek koyun; örneğin, https://cryptic-headland-94862.herokuapp.com/https://example.com .
Bu nedenle, https: //cors-anywhere.herokuapp.com'u kullanmaya çalıştığınızda, aşağı olduğunu (bazen bazen olur) bulursanız, bir Heroku hesabı almayı (zaten yapmadıysanız) düşünün ve 2 veya Heroku üzerinde kendi CORS Anywhere sunucunuzu dağıtmak için yukarıdaki adımları uygulamanız gerekir.
İster kendi kendinize çalıştırın, ister https://cors-anywhere.herokuapp.com veya başka bir açık proxy kullanın, bu çözüm, istek tarayıcıları bir CORS ön kontrol OPTIONSisteği yapmaya yönlendiren bir istek olsa bile çalışır; çünkü bu durumda, proxy ayrıca ön kontrolün başarılı olması için gereken Access-Control-Allow-Headersve Access-Control-Allow-Methodsbaşlıklarını da geri gönderir .
CORS ön kontrolünden nasıl kaçınılır?
Sorudaki kod, bir Authorizationbaşlık gönderdiğinden CORS ön kontrolünü tetikler .
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
Bu olmasa bile, Content-Type: application/jsonbaşlık ön kontrolünü de tetikleyecektir.
“Ön kontrol” ne anlama gelir: tarayıcı POSTsöz konusu kodda denemeden önce, OPTIONSsunucuya bir istek gönderir - sunucunun ve başlıklarını POSTiçeren bir çapraz menşe almayı Authorizationseçip Content-Type: application/jsonseçmediğini belirlemek için.
Küçük bir kıvrılma komut dosyası ile oldukça iyi çalışıyor - verilerimi aldım.
Doğru bir şekilde test curletmek için OPTIONS, tarayıcının gönderdiği ön kontrol isteğini taklit etmelisiniz :
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"
… https://the.sign_in.urlYerine gerçek sign_inURL'niz ne olursa olsun .
Tarayıcının bu OPTIONSistekte görmesi gereken yanıt şu başlıkları içermelidir:
Access-Control-Allow-Origin: http://127.0.0.1:3000
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type, Authorization
Eğer OPTIONSyanıt bu başlıkları içermez, tarayıcı hemen orada duracak ve hatta gönderme girişiminde asla POSTisteği. Ayrıca, yanıtın HTTP durum kodu 2xx (genellikle 200 veya 204) olmalıdır. Başka bir durum kodu varsa, tarayıcı burada durur.
Söz konusu sunucu, OPTIONSisteğe 501 durum koduyla yanıt veriyor. Bu, görünüşe göre OPTIONSisteklere destek uygulamadığını belirtmeye çalıştığı anlamına geliyor . Diğer sunucular genellikle bu durumda 405 "Yönteme izin verilmiyor" durum kodu ile yanıt verir.
Dolayısıyla POST, sunucu bu OPTIONSisteğe 405 veya 501 veya 200 veya 204 dışında bir şeyle yanıt verirse veya gerekli olanlara yanıt vermezse , ön uç JavaScript kodunuzdan doğrudan bu sunucuya istekte bulunamazsınız. yanıt başlıkları.
Söz konusu vaka için ön kontrol tetiklemekten kaçınmanın yolu:
- sunucu bir
Authorizationistek üstbilgisi gerektirmediyse ancak bunun yerine (örneğin) POSTisteğin gövdesine katıştırılmış kimlik doğrulama verilerine veya bir sorgu parametresi olarak kullanıldıysa
- sunucu
POSTgövdenin bir Content-Type: application/jsonmedya türüne sahip olmasını gerektirmediyse, bunun yerine POSTgövdeyi değeri JSON verisi olan (veya her neyse) application/x-www-form-urlencodedadlı bir parametre ile kabul jsonettiğinde
“Access-Control-Allow-Origin üstbilgisi joker karakter olmamalıdır” sorunları nasıl düzeltilir
Başka bir hata mesajı alıyorum:
Yanıttaki 'Access-Control-Allow-Origin' üstbilgisinin değeri, isteğin kimlik bilgileri modu 'dahil' olduğunda '*' joker karakteri olmamalıdır. Bu nedenle ' http://127.0.0.1:3000 ' kaynağına erişim izni verilmiyor. XMLHttpRequest tarafından başlatılan isteklerin kimlik bilgileri modu withCredentials özniteliği tarafından denetlenir.
Kimlik bilgileri içeren bir istek için tarayıcılar, Access-Control-Allow-Originyanıt üstbilgisinin değeri ise ön uç JavaScript kodunuzun yanıta erişmesine izin vermez *. Bunun yerine, bu durumda değer, ön uç kodunuzun kökeni ile tam olarak eşleşmelidir http://127.0.0.1:3000.
MDN HTTP erişim denetimi (CORS) makalesinde Kimlik doğrulamalı istekler ve joker karakterler konusuna bakın.
İsteği gönderdiğiniz sunucuyu kontrol ederseniz, bu durumla başa çıkmanın yaygın bir yolu, sunucuyu Originistek üstbilgisinin değerini alacak şekilde yapılandırmak ve bunu Access-Control-Allow-Originyanıt üstbilgisinin değerine yansıtır / yansıtmaktır . Örneğin, nginx ile:
add_header Access-Control-Allow-Origin $http_origin
Ama bu sadece bir örnek; diğer (web) sunucu sistemleri, yankı değerlerini yansıtmak için benzer yollar sağlar.
Chrome kullanıyorum. Ayrıca bu Chrome CORS Eklentisini kullanmayı denedim
Görünüşe göre Chrome CORS eklentisi Access-Control-Allow-Origin: *, tarayıcının gördüğü yanıta basitçe basitçe bir başlık ekliyor . Eklenti daha akıllı olsaydı, yapacağı şey o sahte Access-Control-Allow-Originyanıt başlığının değerini ön uç JavaScript kodunuzun gerçek kaynağına ayarlamaktır http://127.0.0.1:3000.
Bu yüzden test için bile bu eklentiyi kullanmaktan kaçının. Bu sadece dikkat dağıtıcı. Sunucudan gelen yanıtları tarayıcı filtrelemeden test etmek istiyorsanız curl -H, yukarıdaki gibi kullanmanız daha iyi olur .
Sorudaki istek için ön uç JavaScript kodu fetch(…):
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
Bu çizgileri kaldırın. Access-Control-Allow-*Başlık olduğu tepki başlıkları. Onları hiçbir zaman bir istekte göndermek istemezsiniz. Sahip olacağınız tek etki, bir tarayıcıyı ön kontrol yapmak için tetiklemektir.