2010-11-18 27 views
5

JSON etrafındaki güvenlik parçasını anlamakta biraz sıkıntı çekiyorum çünkü çoğu zaman teoride çalışmam gereken şeyler işe yaramıyor. AFAIK, A alanında bulunan bir sayfadaki bir komut dosyasından gelen çağrıların, bir etki alanından B verileri alması beklenmemektedir. Ancak, aşağıdaki kodda, bir dış etki alanına yapılan çağrılar başarısız olur, diğeri ise geçer. Ve ikisi de paketlenmiş JSON çağrıları (jsonp) değildir.Neden bazı etki alanları arası JSON istekleri başarısız oluyor, ancak diğerleri çalışmıyor?

Bu neden? Her ikisine de tarayıcı güvenlik kontrolünden izin verilmemeli mi? Aynı sonuçları Chrome ve Firefox'ta da alıyorum. Ben dropbox.com aşağıda html-sayfa barındıracaktır ederseniz Chrome bana bu hata mesajını veriyor:

XMLHttpRequest http://www.odinfond.no/rest/fund/calc/fundReturn?&id=300&oneTimeInvestment=100000&oneTimeInvestmentDate=2009-11-01&endDate=2010-11-01&currency=NOK yükleyemez. Yönlendiren http://dl.dropbox.com , Erişim-Denetim-İzin-Kökeni tarafından izin verilmez.

Aradan geçiş yapılıyorsa JSON yanıtı, this direct link tıklanarak görülebilir. Diğer hizmete yapılan çağrı başarıyla geri döner. Aşağıdaki kodu dropbox'ta barındırıyorum. Try it out here.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> 

    <title>JSON/JSONP test</title> 
    <script src="jquery.js" type="text/javascript"></script> 
</head> 

<body> 
    <script> 
    service = 'http://www.odinfond.no/rest/fund/calc/fundReturn?'; 
    parameters = { 
    id: '300', 
    oneTimeInvestment:'100000', 
    oneTimeInvestmentDate:'2009-11-01', 
    endDate:'2010-11-01', 
    currency:'NOK' 
    } 
    $.getJSON(service, parameters, function(data) { 
    alert("Success"); 
    }); 

    service = 'http://ws.geonames.org/postalCodeLookupJSON?' 
    parameters = { 
    postalcode:1540, 
    country:'NO' 
    } 
    $.getJSON(service, parameters, function(data) { 
    alert(data.postalcodes[0].adminName2); 
    }); 
    </script> 
    <p>Use Firebug to see JSON response</p> 
</body> 
</html> 

cevap

6

Çalışmaya istek bir yanıt başlığını sahip olduğunu fark edeceksiniz:

Access-Control-Allow-Origin: * 

Bu senaryoya tepki kullanılabilir hale getirmek için tarayıcıyı boşaltır şeydir.

'*' bir ana makine adı, erişim yalnızca izin verilen halinde geçerli belgenin makine adı ise (istek daima yapılan olduğunu unutmayın, aynı kökenli ilke yalnızca tepki komut dosyası veya olmasın için erişilebilir olup olmadığını etkiler) maçları Access-Control-Allow-Origin başlık

+0

Teşekkür ederim, bu mükemmel bir anlam ifade etti! İsteklerin hemen hemen özdeş olduğunu düşündüm, ancak yanıt üstbilgisinde fark hiç fark etmedim :-) – oligofren

0

source code sörf yaparak, o $ .ajax() uzak URL'ler algılar ve eski güzel senaryo etiketleriyle (XMLHttpRequest ) AJAX değiştirir anlaşılmaktadır:

// Build temporary JSONP function 
    if (s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url))) { 
     jsonp = s.jsonpCallback || ("jsonp" + jsc++); 

     // Replace the =? sequence both in the query string and the data 
     if (s.data) { 
      s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1"); 
     } 

     s.url = s.url.replace(jsre, "=" + jsonp + "$1"); 

     // We need to make sure 
     // that a JSONP style response is executed properly 
     s.dataType = "script"; 

     // Handle JSONP-style loading 
     var customJsonp = window[ jsonp ]; 

     window[ jsonp ] = function(tmp) { 
      if (jQuery.isFunction(customJsonp)) { 
       customJsonp(tmp); 

      } else { 
       // Garbage collect 
       window[ jsonp ] = undefined; 

       try { 
        delete window[ jsonp ]; 
       } catch(jsonpError) {} 
      } 

      data = tmp; 
      jQuery.handleSuccess(s, xhr, status, data); 
      jQuery.handleComplete(s, xhr, status, data); 

      if (head) { 
       head.removeChild(script); 
      } 
     }; 
    } 

[...]

// Matches an absolute URL, and saves the domain 
    var parts = rurl.exec(s.url), 
     remote = parts && (parts[1] && parts[1].toLowerCase() !== location.protocol || parts[2].toLowerCase() !== location.host); 

    // If we're requesting a remote document 
    // and trying to load JSON or Script with a GET 
    if (s.dataType === "script" && type === "GET" && remote) { 
     var head = document.getElementsByTagName("head")[0] || document.documentElement; 
     var script = document.createElement("script"); 
     if (s.scriptCharset) { 
      script.charset = s.scriptCharset; 
     } 
     script.src = s.url; 

     // Handle Script loading 
     if (!jsonp) { 
      var done = false; 

      // Attach handlers for all browsers 
      script.onload = script.onreadystatechange = function() { 
       if (!done && (!this.readyState || 
         this.readyState === "loaded" || this.readyState === "complete")) { 
        done = true; 
        jQuery.handleSuccess(s, xhr, status, data); 
        jQuery.handleComplete(s, xhr, status, data); 

        // Handle memory leak in IE 
        script.onload = script.onreadystatechange = null; 
        if (head && script.parentNode) { 
         head.removeChild(script); 
        } 
       } 
      }; 
     } 

     // Use insertBefore instead of appendChild to circumvent an IE6 bug. 
     // This arises when a base node is used (#2709 and #4378). 
     head.insertBefore(script, head.firstChild); 

     // We handle everything using the script element injection 
     return undefined; 
    } 
+0

Bu snippet'in ilk satırı, yalnızca, yalnızca {dataType: "komut dosyası"} 'yı AJAX çağrısı – Gareth

+0

'a ilettiğinizde gerçekleştiğini gösterir. 'S.dataType' değerinin değiştirildiği önceki bir alıntı ekledim. –

İlgili konular