Baru-baru ini, ajax menghadapi masalah merentas domain semasa mengakses perkhidmatan web saya mencari maklumat dalam talian dan meringkaskannya seperti berikut (banyak daripadanya disalin daripada ringkasan orang lain yang mereka fikir bagus)
<
Mari mulakan dengan kod yang saya laksanakan:
Kod bahagian hadapan:
$.ajax({ type: "get", url: "http://localhost/Service1.asmx/getElevatorStatusJsonData?jsoncallback=?", dataType: "jsonp", jsonp: "json", data: "", success: function (result) { var data = eval(result); for (var i = 0; i < data.length; i++) { alert(data[i].ID + "--" + data[i].Name); } }, error: function (a, b, c) { alert(c); } });
Kod pelayan:
/// <summary> /// 获取状态数据信息 /// </summary> /// <returns></returns> [WebMethod] public void getElevatorStatusJsonData() { List<List<DeviceInfo>> elevatordatas = new List<List<DeviceInfo>>(); List<SendDicdate> searchList = XmlSerializeHelper.XmlDeserializeFromFile<List<SendDicdate>>(@ConfigUtil.servicePath + ConfigUtil.getConfigByKey("xmlPath") + "查询指令信息.xml", Encoding.UTF8); foreach (SendDicdate item in searchList) { string key = item.portno + "-" + item.bordrate + "-" + item.sendtype; List<DeviceInfo> deviceInfoList = (List<DeviceInfo>)Context.Cache.Get(key); elevatordatas.Add(deviceInfoList); } String result = ""; DataContractJsonSerializer json = new DataContractJsonSerializer(elevatordatas.GetType()); using (MemoryStream stream = new MemoryStream()) { json.WriteObject(stream, elevatordatas); result = Encoding.UTF8.GetString(stream.ToArray()); } String jsoncallback = HttpContext.Current.Request["jsoncallback"]; result = jsoncallback + '(' + result + ')'; HttpContext.Current.Response.Write(result); HttpContext.Current.Response.End(); }
c#
Di atas ialah kod pelaksanaan untuk memanggil pelayan c# Berikut adalah bahagian java Parameter mungkin berbeza, tetapi prinsipnya adalah sama
java:
String callbackFunName = context.Request["callbackparam"]; context.Response.Write(callbackFunName + "([ { \"name\":\"John\"}])");
PS: Parameter jsonp klien digunakan untuk menghantar parameter melalui url, dan nama parameter parameter jsonpCallback dilalui Agak sukar untuk menyebutnya dalam istilah awam:
jsonp: ""
jsonpCallback:""
Dengan cara ini: Dalam penyemak imbas Chrome, anda juga boleh menetapkan konteks maklumat pengepala.Response.AddHeader("Access-Control-Allow-Origin", "*"); -permintaan domain Dan tidak perlu menetapkan parameter ajax berikut
dataType : "jsonp", jsonp: "callbackparam", jsonpCallback:"jsonpCallback1"
Data boleh diperolehi melalui permintaan ajax biasa.
Berikut adalah prinsip selepas membaca apa yang orang lain jelaskan, nampaknya masuk akal:
1. Masalah yang terkenal, permintaan langsung Ajax untuk fail biasa mempunyai masalah akses tanpa kebenaran merentas domain Tidak kira sama ada anda adalah halaman statik, halaman web dinamik, perkhidmatan web atau WCF, asalkan ia ialah permintaan merentas domain, ia tidak dibenarkan;
2. Walau bagaimanapun, kami juga mendapati bahawa apabila memanggil fail js pada halaman Web, ia tidak dipengaruhi oleh sama ada ia merentas domain (bukan itu sahaja, kami juga mendapati bahawa semua teg dengan atribut "src" mempunyai silang -keupayaan domain, seperti
3. Ia boleh dinilai bahawa pada peringkat semasa, jika anda ingin mengakses data merentas domain melalui web tulen (kawalan ActiveX, proksi sisi pelayan, Soket Web HTML5 masa hadapan, dll. tidak disertakan), hanya ada satu kemungkinan, dan itu adalah untuk mengakses data dari jauh Pelayan cuba memuatkan data ke dalam fail format js untuk panggilan pelanggan dan pemprosesan selanjutnya;
4. Kami kebetulan sudah mengetahui bahawa terdapat format data aksara tulen yang dipanggil JSON yang boleh menerangkan data kompleks dengan ringkas Apa yang lebih baik ialah JSON juga disokong secara asli oleh js, jadi pelanggan boleh memproses data dalam format ini hampir. seperti yang dikehendaki ;
5. Dengan cara ini, penyelesaiannya sudah sedia Pelanggan web memanggil fail format js yang dijana secara dinamik pada pelayan merentas domain (biasanya dengan JSON sebagai akhiran) dengan cara yang sama seperti skrip panggilan jelas bahawa sebab mengapa pelayan memerlukan Tujuan menjana fail JSON secara dinamik adalah untuk memuatkan data yang diperlukan oleh klien ke dalamnya.
6. Selepas pelanggan berjaya memanggil fail JSON, ia akan memperoleh data yang diperlukannya adalah untuk memproses dan memaparkannya mengikut keperluannya sendiri Kaedah mendapatkan data jauh ini kelihatan seperti AJAX , tetapi ia sebenarnya tidak sama.
7. Untuk memudahkan pelanggan menggunakan data, protokol penghantaran tidak formal telah dibentuk secara beransur-ansur kemudian pelayan mengembalikan data Parameter panggil balik ini akan digunakan sebagai nama fungsi untuk membungkus data JSON, supaya pelanggan boleh menyesuaikan fungsinya sendiri untuk memproses data yang dikembalikan secara automatik.
Pembangun pintar boleh dengan mudah berfikir bahawa selagi skrip js yang disediakan oleh pelayan dijana secara dinamik, pemanggil boleh lulus parameter untuk memberitahu pelayan "Saya mahu js yang memanggil kod fungsi XXX, sila kembalikan kepada saya", jadi pelayan boleh menjana skrip js dan bertindak balas mengikut keperluan pelanggan.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title></title><script type="text/javascript">// 得到航班信息查询结果后的回调函数var flightHandler =function(data){ alert('你查询的航班结果是:piao价 '+ data.price +' 元,'+'余piao '+ data.tickets +' 张。'); }; // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)var url ="http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler"; // 创建script标签,设置其属性var script = document.createElement('script'); script.setAttribute('src', url); // 把script标签加入head,此时调用开始 //document.getElementsByTagName('head')[0].appendChild(script); </script></head><body></body></html> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Untitled Page</title><script type="text/javascript" src=jquery.min.js"></script><script type="text/javascript"> jQuery(document).ready(function(){ $.ajax({ type: "get", async: false, url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998", dataType: "jsonp", jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback) jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据 success: function(json){ alert('您查询到航班信息:piao价: '+ json.price +' 元,余piao: '+ json.tickets +' 张。'); }, error: function(){ alert('fail'); } }); }); </script></head><body></body></html>
Bukankah ia sedikit pelik? Mengapa saya tidak menulis fungsi flightHandler kali ini? Dan ia sebenarnya berjaya! Haha, ini adalah kredit jQuery Apabila jquery mengendalikan ajax jenis jsonp (saya masih tidak boleh mengeluh, walaupun jquery juga mengklasifikasikan jsonp ke dalam ajax, mereka benar-benar bukan perkara yang sama), ia secara automatik menghasilkannya untuk anda Adakah bagus untuk memanggil semula fungsi dan mengeluarkan data untuk kaedah atribut kejayaan untuk dipanggil?