SEÇENEKLER ön kontrol isteği nasıl atlanır?


93

Şimdi mobil web sitesine dönüştürülmekte olan bir PhoneGap uygulaması geliştirdim. Küçük bir aksaklık dışında her şey sorunsuz çalışıyor. Uygulamada iyi çalışan ancak mobil web sitesi sürümünde başarısız olan bir POST isteği aracılığıyla belirli bir üçüncü taraf API kullanıyorum.

Daha yakından baktıktan sonra AngularJS (sanırım tarayıcı aslında) önce bir OPTIONS isteği gönderiyor gibi görünüyor. Bugün CORS hakkında çok şey öğrendim, ancak tamamen nasıl devre dışı bırakacağımı çözemiyorum. Bu API'ye erişimim yok (bu yüzden bu tarafta değişiklik yapmak imkansız), ancak üzerinde çalıştığım etki alanını Access-Control-Allow-Origin başlıklarına eklediler.

Bahsettiğim kod bu:

        var request = {
                language: 'fr',
                barcodes: [
                    {
                        barcode: 'somebarcode',
                        description: 'Description goes here'
                    }
                ]
            };
        }
        var config = {
            headers: { 
                'Cache-Control': 'no-cache',
                'Content-Type': 'application/json'
            }
        };
        $http.post('http://somedomain.be/trackinginfo', request, config).success(function(data, status) {
            callback(undefined, data);
        }).error(function(data, status) {
            var err = new Error('Error message');
            err.status = status;
            callback(err);
        });

Tarayıcının (veya AngularJS'nin) bu OPTIONS isteğini göndermesini ve yalnızca gerçek POST isteğine geçmesini nasıl engelleyebilirim? AngularJS 1.2.0 kullanıyorum.

Şimdiden teşekkürler.

Yanıtlar:


101

Ön kontrol, İçerik Türünüz tarafından tetikleniyor application/json. Bunu önlemenin en basit yolu, İçerik Türünü text/plainsizin durumunuzda olacak şekilde ayarlamaktır . application/x-www-form-urlencoded& multipart/form-dataİçerik Türleri de kabul edilebilir, ancak elbette istek yükünüzü uygun şekilde biçimlendirmeniz gerekir.

Bu değişikliği yaptıktan sonra hala bir ön kontrol görüyorsanız, Angular da isteğe bir X başlığı ekliyor olabilir.

Veya onu tetikleyecek başlıklarınız (Yetkilendirme, Önbellek-Kontrolü ...) olabilir, bakınız:


9
Bu doğru cevaptır - Content-Type ve Cache-Control başlıklarınız bir ön kontrol isteğini tetikliyor. İçerik Türü metin / düz ve birkaç başka düz GET, önceden kontrol edilmemiş bir isteği tetiklemenin tek yoludur. Bakınız: developer.mozilla.org/en-US/docs/HTTP/…
Jeff Hubbard

Ah evet, Cache-Control'ü unuttum.
Ray Nicholus

17
Özel bir başlık da ön kontrolü tetikleyecektir.
Sébastien Deprez

2
OPTIONs testini önlemek için içerik türünü değiştirmek cevap değildir. İçerik türü ne olursa olsun içerik türüyle eşleşmelidir
ekerner

tarayıcı atıyorsa ve arka uçta, Http yöntemi OPTIONS engellenirse, OPTIONS başarısız olduğu için tarayıcının POST / PUT için karşılık gelen API'yi çağırmaması gibi bir etkisi olur mu?
P Satish Patro

16

Ray'in söylediği gibi, içerik başlığını şu şekilde değiştirerek durdurabilirsiniz:

 $http.defaults.headers.post["Content-Type"] = "text/plain";

Örneğin -

angular.module('myApp').factory('User', ['$resource','$http',
    function($resource,$http){
        $http.defaults.headers.post["Content-Type"] = "text/plain";
        return $resource(API_ENGINE_URL+'user/:userId', {}, {
            query: {method:'GET', params:{userId:'users'}, isArray:true},
            getLoggedIn:{method:'GET'}
        });
    }]);

Veya doğrudan bir aramaya -

var req = {
 method: 'POST',
 url: 'http://example.com',
 headers: {
   'Content-Type': 'text/plain'
 },
 data: { test: 'test' }
}

$http(req).then(function(){...}, function(){...});

Bu, herhangi bir uçuş öncesi seçenek talebi göndermeyecektir.

NOT: İsteğin herhangi bir özel başlık parametresi olmamalıdır. İstek başlığı herhangi bir özel başlık içeriyorsa, tarayıcı uçuş öncesi istekte bulunacaktır, bundan kaçınamazsınız.


1
Bunu sadece ile nasıl yapmalıyım $http?
Learnercys

Teşekkürler, yaptığım şeye benzer. Tek değişiklik yöntem GETve fazladan bir başlıktır Authorization. Ama yine de ön kontrol gönderiyor.
Learnercys

1
İsteğinizi buraya yapıştırabilir misiniz? kıvrılma veya başka bir şey olarak? Belki Yetkilendirme başlığından dolayı, kaldırmayı deneyin ve sonra deneyin. Özel başlıklar gönderiyorsanız, angular, uçuş öncesi istek gönderir.
vivex

pastebin.com/vRDeFiH2 Birincisi $ http isteği, ikincisi ise geçerli bir istek. postacı tarafından
oluştur

2

Belirli türden etki alanları arası AJAX isteklerini gerçekleştirirken, CORS'u destekleyen modern tarayıcılar, eylemi gerçekleştirme iznine sahip olup olmadıklarını belirlemek için fazladan bir "ön kontrol" isteği ekleyecektir. Örnek sorgudan:

$http.get( ‘https://example.com/api/v1/users/’ +userId,
  {params:{
           apiKey:’34d1e55e4b02e56a67b0b66’
          }
  } 
);

Bu parçanın bir sonucu olarak, adrese iki istek (SEÇENEKLER ve GET) gönderildiğini görebiliriz. Sunucudan gelen yanıt, GET sorgusunun izin verilebilirliğini onaylayan başlıklar içerir. Sunucunuz bir OPTIONS isteğini doğru şekilde işleyecek şekilde yapılandırılmamışsa, istemci istekleri başarısız olur. Örneğin:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: accept, origin, x-requested-with, content-type
Access-Control-Allow-Methods: DELETE
Access-Control-Allow-Methods: OPTIONS
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Methods: GET
Access-Control-Allow-Methods: POST
Access-Control-Allow-Orgin: *
Access-Control-Max-Age: 172800
Allow: PUT
Allow: OPTIONS
Allow: POST
Allow: DELETE
Allow: GET

2

Bence en iyi yol, isteğin "SEÇENEKLER" türünde olup olmadığını kontrol etmektir. Benim için çalıştı.

express.use('*',(req,res,next) =>{
      if (req.method == "OPTIONS") {
        res.status(200);
        res.send();
      }else{
        next();
      }
    });

Çalışır, ancak OWASP'de SEÇENEKLER'in gösterilmemesi tavsiye edilir. Bunu arka uçta / barındırılan hizmette (Nginx, Apache) vb.
Engelliyorsunuz

0

Ön kontrol, tarayıcı tarafından uygulanan bir web güvenlik özelliğidir. Chrome için --disable-web-security bayrağını ekleyerek tüm web güvenliğini devre dışı bırakabilirsiniz.

Örneğin: "C: \ Program Files \ Google \ Chrome \ Application \ chrome.exe" --disable-web-security --user-data-dir = "C: \ newChromeSettingsWithoutSecurity". Önce yeni bir Chrome kısayolu oluşturabilir, özelliklerine gidebilir ve yukarıdaki gibi hedefi değiştirebilirsiniz. Bu yardımcı olmalı!


OP'nin müşterilerine sadece bir özelliği etkinleştirmek için tarayıcı güvenliğini kapatmasını söylemesini gerçekten bekleyemezsiniz, değil mi ?!
svarog

@svarog bu çoğunlukla geliştirme amaçlıdır, çoğunlukla üretim sunucusunda bu sorunla karşılaşmayacaksınız.
Arijit Patra

tarayıcı atıyorsa ve arka uçta, Http yöntemi OPTIONS engellenirse, OPTIONS başarısız olduğu için tarayıcının POST / PUT için karşılık gelen API'yi çağırmaması gibi bir etkisi olur mu?
P Satish Patro

-2

içerik türünü tanımsız olarak ayarlamak, javascript'in başlık verilerini olduğu gibi geçirmesine ve varsayılan açısal $ httpProvider başlık yapılandırmalarının üzerine yazılmasına neden olur. Angular $ http Belgeleri

$http({url:url,method:"POST", headers:{'Content-Type':undefined}).then(success,failure);
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.