jQuery AJAX web alanları arası


477

İşte iki sayfa: test.php ve testserver.php.

test.php

<script src="scripts/jq.js" type="text/javascript"></script>
<script>
    $(function() {
        $.ajax({url:"testserver.php",
            success:function() {
                alert("Success");
            },
            error:function() {
                alert("Error");
            },
            dataType:"json",
            type:"get"
        }
    )})
</script>

testserver.php

<?php
$arr = array("element1",
             "element2",
             array("element31","element32"));
$arr['name'] = "response";
echo json_encode($arr);
?>

Şimdi benim sorunum: bu dosyaların her ikisi de aynı sunucuda (localhost veya web sunucusu) olduğunda, çalışır ve alert("Success")çağrılır; Farklı sunucularda ise, yani web sunucusunda testserver.php ve localhost üzerinde test.php, çalışmıyor ve alert("Error")çalışıyor. Ajax içindeki URL http://domain.com/path/to/file/testserver.php olarak değiştirilse bile


38
Durmak isteyenler için. Web alanları arası javascript çağrılarının nasıl çalıştığı hakkında bir fikir edinmek için bunu okuyun stackoverflow.com/a/11736771/228656
Abdul Munim

1
Burada bu soru için bir cevap yazdım: jQuery AJAX ile çapraz etki alanı html sayfası yükleniyor - sonuncusu, https destekliyor
jherax

Yanıtlar:


412

JSONP kullanın .

jQuery:

$.ajax({
     url:"testserver.php",
     dataType: 'jsonp', // Notice! JSONP <-- P (lowercase)
     success:function(json){
         // do stuff with json (in this case an array)
         alert("Success");
     },
     error:function(){
         alert("Error");
     }      
});

PHP:

<?php
$arr = array("element1","element2",array("element31","element32"));
$arr['name'] = "response";
echo $_GET['callback']."(".json_encode($arr).");";
?>

Yankı yanlış olabilir, php kullandığımdan beri bir süre oldu. Her durumda callbackName('jsonString')tırnak bildirimi çıktı gerekir . jQuery kendi geri arama adını iletecektir, bu yüzden bunu GET parametrelerinden almanız gerekir.

Stefan Kendall'ın yayınladığı gibi, $ .getJSON () stenografi yöntemidir, ancak 'callback=?'URL'ye GET parametresi olarak eklemeniz gerekir (evet, değer ?, JQuery bunu kendi oluşturulan geri arama yöntemiyle değiştirir).


2
callbackName('/* json */')Bunun yerine neden geri dönmeniz gerekiyor callbackName(/* json */)?
Eric

3
@eric geri arama bir JSON dizesi bekler. Teorik olarak, bir nesne de işe yarayabilir, ancak jQuery'nin buna nasıl yanıt verdiğinden emin olmayabilir, bir hata atabilir veya sessizce başarısız olabilir.
BGerrissen

Aşağıdaki hatayı alıyorum. Sözdizimi Hatası: eksik; önce {"ResultCode" ifadesi: 2}. Burada {"ResultCode": 2} yanıttır. Lütfen tavsiye.
user2003356

@ user2003356, JSONP yerine düz JSON döndürüyor gibi görünüyor. Gibi bir şey döndürmeniz gerekir: callbackFunction ({"ResultCode": 2}). jQuery isteğe 'geri çağrı' parametresini GQ parametresini ekler, bu jquery tarafından kullanılan geri çağırma işlevinin adıdır ve yanıta eklenmelidir.
BGerrissen

2
Bugün 2016. CORS artık sadece bir saldırı olarak tanımlanabilen JSONP'nin aksine yaygın olarak desteklenen bir standarttır. @ joshuarh'ın aşağıdaki cevabı şimdi tercih edilmelidir.
Vicky Chijwani

202

JSONP iyi bir seçenektir, ancak daha kolay bir yol vardır. Access-Control-Allow-OriginBaşlığı sunucunuzda kolayca ayarlayabilirsiniz . Bunu ayarlamak *, herhangi bir alan adından alanlar arası AJAX isteklerini kabul eder. ( https://developer.mozilla.org/en/http_access_control )

Bunu yapmanın yöntemi elbette dilden dile değişecektir. İşte Raylarda:

class HelloController < ApplicationController
  def say_hello
    headers['Access-Control-Allow-Origin'] = "*"
    render text: "hello!"
  end
end

Bu örnekte, say_helloeylem herhangi bir alan adından AJAX isteklerini kabul edecek ve "merhaba!"

İşte döndürebileceği başlıklara bir örnek:

HTTP/1.1 200 OK 
Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: text/html; charset=utf-8
X-Ua-Compatible: IE=Edge
Etag: "c4ca4238a0b923820dcc509a6f75849b"
X-Runtime: 0.913606
Content-Length: 6
Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
Date: Thu, 01 Mar 2012 20:44:28 GMT
Connection: Keep-Alive

Olduğu kadar kolay, bazı tarayıcı sınırlamaları var. Bkz. Http://caniuse.com/#feat=cors .


12
Jsonp gönderi, koy ve sil özelliğini desteklemedi. Çözümünüz harika çalışıyor.
TonyTakeshi

35
PHP başlığında ("Access-Control-Allow-Origin: *");
SparK

9
@Warrior jQuery .post()yöntemini kullanıyorsanız, jQuery'de etki alanları arası desteği etkinleştirmeniz gerekir. Bu ile yapılır: $.support.cors = true.
Friederike

21
Bir sunucuyu bu şekilde yapılandırmanın güvenlik üzerindeki etkileri nelerdir?
Jon Schneider

19
"*" Wilcardını kullanmak yerine yalnızca verileri paylaşmak istediğiniz alan adlarına izin vermek daha iyi olur.
Sebastián Grignoli

32

Bunu HTTP üstbilgisi aracılığıyla Access-Control-Allow-Origin ekleyerek denetleyebilirsiniz . Bunu * olarak ayarlamak, herhangi bir alan adından alanlar arası AJAX isteklerini kabul eder.

PHP'yi kullanmak gerçekten çok basit, alan adınızın dışında erişmek istediğiniz komut dosyasına aşağıdaki satırı eklemeniz yeterlidir:

header("Access-Control-Allow-Origin: *");

Httpd.conf dosyasında mod_headers modülünü etkinleştirmeyi unutmayın.


günümü kurtardın.
NomanJaved

20

Aynı Menşe Politikasına bir göz atmanız gerekir :

Hesaplamada, aynı kaynak ilkesi, JavaScript gibi bir dizi tarayıcı tarafı programlama dili için önemli bir güvenlik konseptidir. Bu politika, aynı siteden gelen sayfalarda çalışan komut dosyalarının belirli bir kısıtlama olmaksızın birbirlerinin yöntemlerine ve özelliklerine erişmesine izin verir, ancak farklı sitelerdeki sayfalardaki yöntem ve özelliklerin çoğuna erişimi engeller.

Veri alabilmeniz için şu olması gerekir:

Aynı protokol ve ana bilgisayar

Geçici çözüm için JSONP uygulamanız gerekir.


17

Web sayfasını yerel diskten "file: /// C: /test/htmlpage.html" yüklemek, "http: //localhost/getxml.php" url dosyasını çağırmak ve IE8 + ve Firefox12 + tarayıcılarında kullanmak, jQuery v1 kullanmak zorunda kaldım .7.2 ortak plaka kodunu en aza indirmek için lib. Sonunda onlarca makale okuduktan sonra anladım. İşte özetim.

  • sunucu komut dosyası (.php, .jsp, ...) http yanıt başlığını döndürmelidir Access-Control-Allow-Origin: *
  • jQuery ajax kullanmadan önce javascript içinde bu bayrağı ayarlayın: jQuery.support.cors = true;
  • jQuery ajax işlevini kullanmadan önce bir veya her seferinde bayrak ayarlayabilirsiniz
  • şimdi IE ve Firefox'ta .xml belgesini okuyabilirim. Test etmediğim diğer tarayıcılar.
  • yanıt belgesi düz / metin, xml, json veya başka bir şey olabilir

İşte bazı hata ayıklama sysouts ile örnek jQuery ajax çağrısı.

jQuery.support.cors = true;
$.ajax({
    url: "http://localhost/getxml.php",
    data: { "id":"doc1", "rows":"100" },
    type: "GET",
    timeout: 30000,
    dataType: "text", // "xml", "json"
    success: function(data) {
        // show text reply as-is (debug)
        alert(data);

        // show xml field values (debug)
        //alert( $(data).find("title").text() );

        // loop JSON array (debug)
        //var str="";
        //$.each(data.items, function(i,item) {
        //  str += item.title + "\n";
        //});
        //alert(str);
    },
    error: function(jqXHR, textStatus, ex) {
        alert(textStatus + "," + ex + "," + jqXHR.responseText);
    }
});

1
Burada bu soru için bir cevap yazdım: jQuery AJAX ile çapraz etki alanı html sayfası yükleniyor - sonuncusu, https destekliyor
jherax

En ateşli nokta için: PHP'de bu satırı betiğe ekleyin:header("Access-Control-Allow-Origin: *");
T30

1
@ yanıtınız için ÇOK çok teşekkür ederim. Bana çok yardımcı oldun. Şerefe.
Luis Milanese

10

Aynı köken politikasının JavaScript'in etki alanlarında istekte bulunmasını engellediği doğrudur, ancak CORS belirtimi yalnızca aradığınız API erişimine izin verir ve geçerli büyük tarayıcı grubu tarafından desteklenir.

İstemci ve sunucu için çapraz kaynak paylaşımının nasıl etkinleştirileceğini görün:

http://enable-cors.org/

"Kaynaklar Arası Kaynak Paylaşımı (CORS), alan sınırları boyunca gerçekten açık erişim sağlayan bir özelliktir. Herkese açık içerik sunuyorsanız, lütfen evrensel JavaScript / tarayıcı erişimi için açmak üzere CORS'u kullanmayı düşünün."



9

Apache sunucusu kullanıyorum, bu yüzden mod_proxy modülünü kullandım. Modülleri etkinleştir:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

Sonra Ekle:

ProxyPass /your-proxy-url/ http://service-url:serviceport/

Son olarak, komut dosyanıza proxy-url iletin.




4

Jquery dokümanlarından ( bağlantı ):

  • Tarayıcı güvenliği kısıtlamaları nedeniyle, "Ajax" isteklerinin çoğu aynı başlangıç ​​politikasına tabidir; istek, farklı bir etki alanından, alt etki alanından veya protokolden başarıyla veri alamıyor.

  • Komut dosyası ve JSONP istekleri aynı kaynak ilkesi kısıtlamalarına tabi değildir.

Bu yüzden istek için jsonp kullanmanız gerektiğini kabul ediyorum. Ama bunu kendim denemedim.


2

Sorununuzu çözmenin 3 yolunu biliyorum:

  1. İlk olarak, her iki alana da erişiminiz varsa aşağıdakileri kullanarak diğer tüm alanlara erişim izni verebilirsiniz:

    header("Access-Control-Allow-Origin: *");

    veya yalnızca .htaccess dosyasına aşağıdaki kodu ekleyerek bir alan adı girin:

    <FilesMatch "\.(ttf|otf|eot|woff)$"> <IfModule mod_headers.c> SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.net|dev02.otherdomain.net)$" AccessControlAllowOrigin=$0 Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin </IfModule> </FilesMatch>

  2. sunucunuzda bir php dosyasına ajax isteğiniz olabilir ve bu php dosyasını kullanarak başka bir etki alanına istek işleyebilirsiniz.

  3. jsonp kullanabilirsiniz, çünkü izne ihtiyacı yoktur. bunun için bizim arkadaşımız @BGerrissen cevap okuyabilirsiniz.

0

Microsoft Azure için biraz farklı.

Azure'un ayarlanması gereken özel bir CORS ayarı var. Aslında sahne arkasında aynı şey, ama sadece joshuarh başlık ayarlamak işe yaramaz. Web alanları arası etkinleştirmeye yönelik Azure belgeleri burada bulunabilir:

https://docs.microsoft.com/en-us/azure/app-service-api/app-service-api-cors-consume-javascript

Hosting platformumun bu özel ayara sahip olduğunu fark etmeden önce birkaç saat boyunca bununla uğraştım.


0

çalışır, tek ihtiyacınız olan:

PHP:

header('Access-Control-Allow-Origin: http://www.example.com');
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');

JS (jQuery ajax):

var getWBody = $.ajax({ cache: false,
        url: URL,
        dataType : 'json',
        type: 'GET',
        xhrFields: { withCredentials: true }
});
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.