Kürzlich stieß Ajax beim Zugriff auf den Webservice auf domänenübergreifende Probleme. Ich suchte online nach Informationen und fasste sie wie folgt zusammen (viele davon wurden aus den Zusammenfassungen anderer Leute kopiert, die sie für gut hielten)
<
Beginnen wir mit meinem implementierten Code:
Frontend-Code:
$.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); } });
Servercode:
/// <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#
Das Obige ist der Implementierungscode zum Aufrufen des C#-Servers. Die Parameter können unterschiedlich sein, aber die Prinzipien sind die gleichen
Java:
String callbackFunName = context.Request["callbackparam"]; context.Response.Write(callbackFunName + "([ { \"name\":\"John\"}])");
PS: Der Parameter jsonp auf dem Client wird verwendet, um Parameter über die URL zu übergeben, und der Parametername des Parameters jsonpCallback ist für Laien etwas schwierig auszudrücken:
jsonp: ""jsonpCallback:""
Übrigens: Im Chrome-Browser können Sie den Header-Informationskontext auch auf der Serverseite festlegen.Response.AddHeader("Access-Control-Allow-Origin", "*"); -Domain-Anfragen. Die folgenden Ajax-Parameter müssen nicht festgelegt werden
dataType : "jsonp", jsonp: "callbackparam", jsonpCallback:"jsonpCallback1"
Das Folgende ist das Prinzip, nachdem ich gelesen habe, was andere erklärt haben, es scheint Sinn zu machen:
1. Ein bekanntes Problem: Die direkte Ajax-Anfrage für normale Dateien hat das Problem des domänenübergreifenden unbefugten Zugriffs, unabhängig davon, ob Sie eine statische Seite, eine dynamische Webseite, einen Webdienst oder WCF verwenden ist eine domänenübergreifende Anfrage, sie ist nicht zulässig;2. Wir haben jedoch auch festgestellt, dass es beim Aufrufen von js-Dateien auf einer Webseite keinen Einfluss darauf hat, ob sie domänenübergreifend ist (nicht nur das, wir haben auch festgestellt, dass alle Tags mit dem Attribut „src“ über Kreuz verfügen -Domänenfunktionen, z. B.
3. Man kann davon ausgehen, dass es zum jetzigen Zeitpunkt nur eine Möglichkeit gibt, wenn Sie domänenübergreifend über reines Web auf Daten zugreifen möchten (ActiveX-Steuerelemente, serverseitige Proxys und zukünftige HTML5-Websockets sind nicht enthalten): und zwar für den Fernzugriff auf Daten. Der Server versucht, die Daten in eine Datei im JS-Format zu laden, damit sie vom Client aufgerufen und weiterverarbeitet werden können.
4. Wir wissen bereits, dass es ein reines Zeichendatenformat namens JSON gibt, das komplexe Daten prägnant beschreiben kann. Was noch besser ist, ist, dass JSON auch nativ von js unterstützt wird, sodass der Client Daten fast in diesem Format verarbeiten kann wie gewünscht. ;
5. Auf diese Weise ist die Lösung fertig. Der Webclient ruft die auf dem domänenübergreifenden Server dynamisch generierte Datei (normalerweise mit JSON als Suffix) auf, genau wie das aufrufende Skript Es ist offensichtlich, dass der Grund, warum der Server eine JSON-Datei dynamisch generiert, darin besteht, die vom Client benötigten Daten in diese Datei zu laden.
6. Nachdem der Client die JSON-Datei erfolgreich aufgerufen hat, erhält er die benötigten Daten. Der Rest besteht darin, sie entsprechend seinen eigenen Anforderungen zu verarbeiten und anzuzeigen. Diese Methode zum Abrufen von Remote-Daten ähnelt AJAX sehr eigentlich nicht dasselbe.
7. Um dem Client die Nutzung von Daten zu erleichtern, hat sich nach und nach ein informelles Übertragungsprotokoll gebildet. Die Leute nennen es JSONP. Einer der wichtigsten Punkte dieses Protokolls besteht darin, Benutzern die Übergabe eines Rückrufparameters an den Server zu ermöglichen Anschließend gibt der Server die Daten zurück. Dieser Rückrufparameter wird als Funktionsname zum Umschließen der JSON-Daten verwendet, sodass der Client seine eigene Funktion anpassen kann, um die zurückgegebenen Daten automatisch zu verarbeiten.
Kluge Entwickler können leicht denken, dass der Aufrufer einen Parameter übergeben kann, um dem Server mitzuteilen: „Ich möchte ein JS, das den XXX-Funktionscode aufruft, bitte zurückgeben, solange das vom Server bereitgestellte JS-Skript dynamisch generiert wird.“ es mir“, damit der Server JS-Skripte generieren und entsprechend den Anforderungen des Clients reagieren kann.
<!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>