HTML5 getirme API'sını kullanarak Access-Control-Allow-Origin başlığına izin ver


91

HTML5 getirme API'sini kullanıyorum.

var request = new Request('https://davidwalsh.name/demo/arsenal.json');

fetch(request).then(function(response) {
    // Convert to JSON
    return response.json();
}).then(function(j) {
    // Yay, `j` is a JavaScript object
    console.log(JSON.stringify(j));
}).catch(function(error) {
    console.log('Request failed', error)
});

Normal json kullanabiliyorum, ancak yukarıdaki api url'sinin verilerini alamıyorum. Şu hata verir:

Getirme API'si https://davidwalsh.name/demo/arsenal.json'u yükleyemiyor . İstenen kaynakta 'Access-Control-Allow-Origin' başlığı yok. Bu nedenle ' http: // localhost ' kaynağına erişime izin verilmiyor. Opak bir yanıt ihtiyaçlarınızı karşılıyorsa, CORS devre dışıyken kaynağı almak için isteğin modunu 'no-cors' olarak ayarlayın.


3. taraf sunucunun ayarlaması gerekir, istemci tarafında yapabileceğiniz hiçbir şey yoktur.
epascarello

@epascarello: Müşteri tarafında yapabiliriz. Sahne arkasında XHR Talebi devam ediyor. Lütfen bunu kontrol edinhttps://davidwalsh.name/fetch
iNikkz

Yanıtlar:


87

Epascarello'nun dediği gibi, kaynağı barındıran sunucunun CORS'u etkinleştirmiş olması gerekir. İstemci tarafında yapabilecekleriniz (ve muhtemelen düşündüğünüz şey), getirme modunu CORS olarak ayarlamaktır (bunun varsayılan ayar olduğuna inanıyorum):

fetch(request, {mode: 'cors'});

Ancak bu yine de sunucunun CORS'u etkinleştirmesini ve alanınızın kaynağı talep etmesine izin vermesini gerektirir.

Check out CORS belgeleri ve bu müthiş Udacity videoyu açıklayan Aynı Kökeni İlkesi .

İstemci tarafında cors'suz modu da kullanabilirsiniz, ancak bu size sadece opak bir yanıt verecektir (gövdeyi okuyamazsınız, ancak yanıt yine de bir servis çalışanı tarafından önbelleğe alınabilir veya bazı API'ler tarafından kullanılabilir <img>) :

fetch(request, {mode: 'no-cors'})
.then(function(response) {
  console.log(response); 
}).catch(function(error) {  
  console.log('Request failed', error)  
});

2
"Ancak bu yine de sunucunun CORS'u etkinleştirmesini ve alanınızın kaynağı talep etmesine izin vermesini gerektiriyor." Başarısız bir şekilde bunu yapmak için talimatlar arıyordum.
jayscript

2
@jayscript genel süreç şu şekilde görünür: istemcide javascript ile çapraz kaynak isteği yapılır. Getirme API'sinde, 'cors' modu tarayıcıya bu isteği yapmasının uygun olmadığını söyler. Bunun yerine 'korsesiz' modunuz olsaydı, tarayıcı isteği durdurur, çünkü bu uygulamanızın kaynağı değildir. Sunucu isteği alacak ve yanıtlayacaktır. Tarayıcı yanıtı uygun CORS başlıkları vardır ve eğer öyleyse, cevap okunacak izin verdiğini doğruladı. Başlıklar yoksa, tarayıcı bir hata atar.
David Scales

1
@jayscript Bu MDN makalesi ayrıntılara giriyor. Esasen, ihtiyacınız olan bir sunucunuz şu üstbilgileri ayarlayın: "Access-Control-Allow-Origin: foo.example ", "Access-Control-Allow-Methods: POST, GET, OPTIONS", "Access-Control-Allow-Headers: X-PINGOTHER, Content-Type ", sırasıyla kökenleri, yöntemleri ve başlıkları etkinleştirir. Kaynak başlığı için tipik olarak '*' kullanılır. Getirme API'sı hakkında bilgi edinmek için bu Google dokümanına ve ilgili codelab'a da bakabilirsiniz: developers.google.com/web/ilt/pwa/working-with-the-fetch-api
David Scales

2
Teşekkür ederim! Bu, API sunucusu herhangi bir başlık içermediğinde farklı bir kökene sahip API sunucusundan veri almanın imkansız olduğunu anlamama yardımcı oluyor. İlgilendiğim özel durumda, API sunucu koduna erişimim vardı ve kendi başıma başlıkları ekleyebildim, bu da getirmeyi etkinleştirdi.
jayscript

Bu aptalca, NO sendingçerezlerle ilgili güvenlik sorunu nedir ve dolayısıyla CORS'a izin verilir?
deathangel908

13

Ön uç kodum http: // localhost: 3000 ve API'm (Arka uç kodu) şu konumda çalışıyordu: http: // localhost: 5000'de çalışıyordu

API'yi çağırmak için getirme API'sini kullanıyordu. Başlangıçta "cors" hatası veriyordu. Sonra bu kodu Arka Uç API koduma ekleyerek her yerden kaynak ve başlığa izin verdim.

let allowCrossDomain = function(req, res, next) {
  res.header('Access-Control-Allow-Origin', "*");
  res.header('Access-Control-Allow-Headers', "*");
  next();
}
app.use(allowCrossDomain);

Ancak sahne, üretim gibi diğer ortamlarda kökenlerinizi kısıtlamalısınız.


21
bu korkunç bir cevap. bu çok büyük bir güvenlik sorunudur. Bunu okuyorsanız LÜTFEN BUNU YAPMAYIN.
Mat Jones

1
Bu yalnızca yerel kurulum içindir. Örneğin hızlı bir resim yapmak için. Evet, diğer konuşlandırılabilir ortamlar için de aynısı geçerliyse bir güvenlik riski vardır. Yerel için öyle hissetmiyorum. "Ancak sahne, üretim gibi diğer ortamlarda kökenlerinizi kısıtlamalısınız"
smsivaprakaash

12

Bu benim için çalıştı:

npm install -g local-cors-proxy

CORS sorunları olan, talep etmek istediğimiz API uç noktası:

https://www.yourdomain.com/test/list

Proxy'yi Başlat:

lcp --proxyUrl https://www.yourdomain.com

 Proxy Active 

 Proxy Url: http://www.yourdomain.com:28080
 Proxy Partial: proxy
 PORT: 8010

Ardından müşteri kodunuzda, yeni API uç noktası:

http://localhost:8010/proxy/test/list

Son sonuç , CORS sorunları olmadan https: //www.alanınız.ie/test/list için bir istek olacaktır !


Pls sunucunun paralel çalıştığından emin olun Yeni cmt-komut penceresi açın ve lcp --proxyUrl alaniniz.com
Govarthanan Venunathan

8

Bunun daha eski bir gönderi olduğunu biliyorum, ancak bu hatayı düzeltmek için işe yarayan şeyin, getirme isteğimde etki alanı adını kullanmak yerine sunucumun IP adresini kullanmak olduğunu buldum. Yani mesela:

#(original) var request = new Request('https://davidwalsh.name/demo/arsenal.json');
#use IP instead
var request = new Request('https://0.0.0.0/demo/arsenal.json');

fetch(request).then(function(response) {
    // Convert to JSON
    return response.json();
}).then(function(j) {
    // Yay, `j` is a JavaScript object
    console.log(JSON.stringify(j));
}).catch(function(error) {
    console.log('Request failed', error)
});

1

Nginx kullanıyorsanız bunu deneyin

#Control-Allow-Origin access

    # Authorization headers aren't passed in CORS preflight (OPTIONS) calls. Always return a 200 for options.
    add_header Access-Control-Allow-Credentials "true" always;
    add_header Access-Control-Allow-Origin "https://URL-WHERE-ORIGIN-FROM-HERE " always;
    add_header Access-Control-Allow-Methods "GET,OPTIONS" always;
    add_header Access-Control-Allow-Headers "x-csrf-token,authorization,content-type,accept,origin,x-requested-with,access-control-allow-origin" always;

    if ($request_method = OPTIONS ) {
        return 200;
    }


1

Veri talep ettiğiniz sunucu tarafında cors başlığını ayarlamanız gerekir. Örneğin, arka uç sunucunuz Ruby on rails'de ise, yanıt göndermeden önce aşağıdaki kodu kullanın. Herhangi bir arka uç sunucusu için aynı başlıklar ayarlanmalıdır.

headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
headers['Access-Control-Request-Method'] = '*'
headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'

-3

Https://expressjs.com/en/resources/middleware/cors.html adresine bakın. Kors kullanmak zorundasınız.

Yüklemek:

$ npm install cors
const cors = require('cors');
app.use(cors());

Bu kodu düğüm sunucunuza koymalısınız.


1
OP'nin sunucusu olup olmadığını ve NodeJ'lerde yazıldığını nasıl anlarsınız?
Marek Szkudelski

Bir düğüm sunucusu oluşturduysanız (geliştirme modu), js'de getirmeyi kullanmak için bu yöntemi kullanabilirsiniz.
Ernersto Pastori
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.