CORS - Bir http talebini 'ön kontrol' nasıl yapar?


94

WCF hizmetine (sahip olduğum) bir çapraz etki alanı HTTP isteği yapmaya çalışıyorum. Etki alanları arası komut dosyası sınırlamalarıyla çalışmak için birkaç teknik okudum. Hizmetimin hem GET hem de POST isteklerini karşılaması gerektiğinden, src'si bir GET isteğinin URL'si olan bazı dinamik betik etiketlerini uygulayamıyorum. Sunucuda değişiklik yapmakta özgür olduğum için, sunucu yanıtlarını "Erişim-Kontrol-İzin Ver" başlığını ve "ön kontrol" isteklerini ve OPTIONS isteğini içerecek şekilde yapılandırmayı içeren bir geçici çözüm uygulamaya başladım. Bu gönderiden bir fikir aldım: CORS'u çalıştırma

Sunucu tarafında, web yöntemim HTTP yanıtına 'Access-Control-Allow-Origin: *' ekliyor. Yanıtların şimdi bu başlığı içerdiğini görebiliyorum. Sorum şu: Bir isteği (SEÇENEKLER) nasıl 'ön kontrol' yapabilirim? GET isteğini yapmak için jQuery.getJSON kullanıyorum, ancak tarayıcı şu kötü şöhretle isteği hemen iptal ediyor:

Kaynak http: // localhost'a Access-Control-Allow-Origin tarafından izin verilmiyor

Bu CORS tekniğine aşina olan var mı? Talebimi önceden kontrol etmek için müşteride hangi değişikliklerin yapılması gerekiyor?

Teşekkürler!

Yanıtlar:


159

Ön kontrol talebi sırasında, aşağıdaki iki başlığı görmelisiniz: Erişim-Kontrol-İstek-Yöntem ve Erişim-Kontrol-İstek-Başlıkları. Bu istek başlıkları, sunucudan gerçek istekte bulunma izni istiyor. Gerçek isteğin işe yaraması için ön kontrol cevabınızın bu başlıkları onaylaması gerekir.

Örneğin, tarayıcının aşağıdaki başlıklarla bir istekte bulunduğunu varsayalım:

Origin: http://yourdomain.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Custom-Header

Sunucunuz daha sonra aşağıdaki başlıklarla yanıt vermelidir:

Access-Control-Allow-Origin: http://yourdomain.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: X-Custom-Header

Access-Control-Allow-Headers yanıt başlığına özellikle dikkat edin. Bu başlığın değeri Access-Control-Request-Headers istek başlığındaki aynı başlıklar olmalıdır ve '*' olamaz.

Bu yanıtı ön kontrol isteğine gönderdikten sonra, tarayıcı asıl isteği yapacaktır. Burada CORS hakkında daha fazla bilgi edinebilirsiniz: http://www.html5rocks.com/en/tutorials/cors/


Access-Control-Allow-Origin'e birden fazla alan ekleyebilir misiniz?
botbot

@botbot Muhtemelen şimdiye kadar bunu çözdünüz, ancak başkalarının yapabileceğini merak ediyorsanızAccess-Control-Allow-Origin: *
Steve Chambers

2
Muhtemelen bir şeyi kaçırdım. Öyleyse iki XMLHttp isteği göndermeli miyim? Ön kontrol için bir tane; başarıya ilişkin yanıtı kontrol edin ve ardından asıl sorguyu gönderin.
Kangkan

15
@Kangkan, ön kontrol isteği göndermek konusunda endişelenmenize gerek yok. İstek bir ön kontrol gerektiriyorsa, tarayıcı bunu sizin için gönderecektir.
monsur

4
Node / expressjs ile sorunumu çözen 'özel ilgi' biti için TEŞEKKÜR EDERİZ ... Bu ön kontrol isteklerini yakalamak için bir filtre ekleyebildim//cors and preflight filtering app.all('*', function(req, res, next){.. //preflight needs to return exact request-header res.set('Access-Control-Allow-Headers', req.headers['access-control-request-headers']); if ('OPTIONS' == req.method) return res.send(204);next(); });
Kurtfm

0

Bu konu 2014 yılına kadar uzanmasına rağmen, sorun birçoğumuz için hala güncel olabilir. İşte jQuery 1.12 / PHP 5.6 bağlamında bununla nasıl başa çıktığım:

  • jQuery, XHR isteğini yalnızca sınırlı başlıklar kullanarak gönderdi; sadece 'Menşe' gönderildi.
  • Ön kontrol talebine gerek yoktu.
  • Sunucunun yalnızca böyle bir isteği algılaması ve "Erişim-Kontrol-İzin Ver-Kaynak:" eklemesi gerekiyordu. $ _SERVER ['HTTP_ORIGIN'] başlığı, bunun çapraz kaynaklı bir XHR olduğunu tespit ettikten sonra.

PHP Kodu örneği:

if (!empty($_SERVER['HTTP_ORIGIN'])) {
    // Uh oh, this XHR comes from outer space...
    // Use this opportunity to filter out referers that shouldn't be allowed to see this request
    if (!preg_match('@\.partner\.domain\.net$@'))
        die("End of the road if you're not my business partner.");

    // otherwise oblige
    header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
}
else {
    // local request, no need to send a specific header for CORS
}

Özellikle, exit;ön kontrol gerekmediği için bir eklemeyin .

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.