เมื่อเร็ว ๆ นี้อาแจ็กซ์พบปัญหาข้ามโดเมนเมื่อเยี่ยมชมเว็บเซิร์ฟเวอร์ ค้นหาข้อมูลออนไลน์และสรุปพวกเขาดังนี้ (หลายคนคิดว่าพวกเขาคัดลอกพวกเขาได้ดี)
<< ใช้ JSON เพื่อถ่ายโอนข้อมูลอาศัย JSONP ไปยัง Domain Cross Domain >>
ก่อนอื่นฉันจะเพิ่มรหัสที่ใช้งาน:
รหัสส่วนหน้า:
$ .ajax ({type: "get", url: "http: //localhost/service1.asmx/getelevatorstatusjsondata? jsoncallback =?", ข้อมูล: "jsonp", jsonp: i ++) {การแจ้งเตือน (ข้อมูล [i] .id + "-" + data [i] .name);รหัสเซิร์ฟเวอร์:
/// <summary> /// รับข้อมูลสถานะข้อมูล //// </summary> /// <return> </returs> [webMethod] โมฆะสาธารณะ GetElevatorStatusJSondata () {รายการ <list <deviceInfo>> eliedaTordataS = รายการใหม่ <รายการ < รายการ <EdmedDicDate> searchList = xmlSerializeHelper.xmldeserializeFromFile <รายการ <senddicdate>> (@configutil.servicepath + configutil.getConfigbykey ("xmlpath") + foreach (รายการ senddicdate ใน SearchList) {String key = item.portno + "-" + item.bordrate + "-" + item.sendtype; รายการ <SeviceInfo> deviceInFolist = (รายการ <SeviceInfo>) context.cache.get (คีย์); Elevatordatas.add (deviceInfolist); } string result = ""; DataContractJSonserializer JSON = ใหม่ DataContractJSonserializer (Elevatordatas.getType ()); การใช้ (MemoryStream Stream = new MemoryStream ()) {json.writeObject (สตรีม, Elevatordatas); result = encoding.utf8.getString (stream.toarray ()); } string jsonCallback = httpContext.current.request ["jsoncallback"]; result = jsonCallback + '(' + ผลลัพธ์ + ')'; httpcontext.current.response.write (ผลลัพธ์); httpContext.current.response.end (); -C#
ข้างต้นคือรหัสการใช้งานที่เรียกเซิร์ฟเวอร์ C# และต่อไปนี้คือฝั่ง Java พารามิเตอร์อาจแตกต่างกัน แต่หลักการเหมือนกัน
Java:
สตริง callbackfunname = context.request ["callbackparam"]; context.response.write (callbackfunname + "([{/" name/":/" john/"}])");PS: พารามิเตอร์ JSONP ของไคลเอนต์ใช้เพื่อส่งผ่านพารามิเตอร์ผ่าน URL และส่งผ่านชื่อพารามิเตอร์ของพารามิเตอร์ JSONPCALLBACK เป็นการยากที่จะออกเสียงและในแง่ง่าย:
JSONP: ""
jsonpcallback: ""
โดยวิธีการ: ในเบราว์เซอร์ Chrome คุณยังสามารถตั้งค่าบริบทข้อมูลส่วนหัว Response.addheader ("การควบคุมการควบคุม-Origin", "*"); บนเซิร์ฟเวอร์เพื่อให้บรรลุวัตถุประสงค์ของคำขอข้ามโดเมนและไม่จำเป็นต้องตั้งค่าพารามิเตอร์ของ AJAX ต่อไปนี้
DataType: "JSONP", JSONP: "CallbackParam", JSONPCALLBACK: "JSONPCALLBACK1"
ข้อมูลสามารถรับได้ในโหมดคำขอ AJAX ปกติ
ต่อไปนี้เป็นหลักการ รู้สึกสมเหตุสมผลมากเมื่อคุณอ่านสิ่งที่คนอื่นอธิบาย:
1. ปัญหาที่รู้จักกันดี AJAX ขอไฟล์ธรรมดาโดยตรงโดยไม่ได้รับอนุญาตให้เข้าถึงข้ามโดเมน ไม่ว่าคุณจะเป็นหน้าคงที่หน้าเว็บไดนามิกบริการเว็บหรือ WCF ตราบใดที่มันเป็นคำขอข้ามโดเมนมันจะไม่ถูกต้อง
2. อย่างไรก็ตามเราพบว่าเมื่อเรียกไฟล์ JS บนหน้าเว็บพวกเขาจะไม่ได้รับผลกระทบจากว่าพวกเขาเป็นโดเมนข้าม (ไม่เพียงแค่นั้นเรายังพบว่าแท็กทั้งหมดที่มีแอตทริบิวต์ "SRC" มีความสามารถข้ามโดเมนเช่น
3. ดังนั้นจึงสามารถตัดสินได้ว่าในขั้นตอนนี้หากคุณต้องการเข้าถึงข้อมูลผ่านโดเมนผ่านเว็บบริสุทธิ์ (การควบคุม ActiveX, พร็อกซีเซิร์ฟเวอร์, HTML5 WebSockets ในอนาคต ฯลฯ คือการพยายามโหลดข้อมูลลงในไฟล์รูปแบบ JS บนเซิร์ฟเวอร์ระยะไกลเพื่อให้ไคลเอนต์โทรและการประมวลผลเพิ่มเติม
4. เรารู้ว่ามีรูปแบบข้อมูลอักขระบริสุทธิ์ที่เรียกว่า JSON ที่สามารถอธิบายข้อมูลที่ซับซ้อนได้อย่างรัดกุม สิ่งที่ดีกว่าคือ JSON ได้รับการสนับสนุนโดย JS ดังนั้นลูกค้าสามารถประมวลผลข้อมูลในรูปแบบนี้ได้เกือบตามที่คุณต้องการ
5. โซลูชันนี้ออกมา ไคลเอนต์เว็บเรียกไฟล์รูปแบบ JS (โดยปกติจะมี JSON เป็นคำต่อท้าย) ที่สร้างขึ้นแบบไดนามิกบนเซิร์ฟเวอร์ข้ามโดเมนในลักษณะเดียวกับสคริปต์การโทร เห็นได้ชัดว่าเหตุผลที่เซิร์ฟเวอร์ต้องการสร้างไฟล์ JSON แบบไดนามิกคือการโหลดข้อมูลที่ลูกค้าต้องการ
6. หลังจากลูกค้าเรียกไฟล์ JSON สำเร็จเขาได้รับข้อมูลที่เขาต้องการ ส่วนที่เหลือคือการประมวลผลและแสดงตามความต้องการของเขาเอง วิธีการรับข้อมูลระยะไกลนี้ดูคล้ายกับอาแจ็กซ์มาก แต่จริงๆแล้วมันแตกต่างกัน
7. เพื่ออำนวยความสะดวกให้ลูกค้าใช้ข้อมูลโปรโตคอลการส่งข้อมูลที่ไม่เป็นทางการได้ถูกสร้างขึ้นอย่างค่อยเป็นค่อยไป ผู้คนเรียกมันว่า JSONP หนึ่งในประเด็นสำคัญของโปรโตคอลนี้คือการอนุญาตให้ผู้ใช้ส่งพารามิเตอร์การโทรกลับไปยังเซิร์ฟเวอร์ เมื่อเซิร์ฟเวอร์ส่งคืนข้อมูลจะใช้พารามิเตอร์การเรียกกลับนี้เป็นชื่อฟังก์ชันเพื่อห่อข้อมูล JSON เพื่อให้ไคลเอนต์สามารถปรับแต่งฟังก์ชั่นของตัวเองเพื่อประมวลผลข้อมูลการส่งคืนโดยอัตโนมัติ
มันเป็นเรื่องง่ายสำหรับนักพัฒนา Smart ที่จะคิดว่าตราบใดที่สคริปต์ JS ที่ให้ไว้โดยเซิร์ฟเวอร์นั้นถูกสร้างขึ้นแบบไดนามิกผู้โทรสามารถผ่านพารามิเตอร์และบอกเซิร์ฟเวอร์ "ฉันต้องการรหัส JS ที่เรียกฟังก์ชัน XXX โปรดส่งคืนให้ฉัน" ดังนั้นเซิร์ฟเวอร์จึงสามารถสร้างสคริปต์ JS และตอบสนองตามความต้องการของลูกค้า
<! doctype html public "-// w3c // dtd xhtml 1.0 transitional // en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> xmlns = "http://www.w3.org/1999/xhtml"> <head> <title> </title> <script type = "text/javascript"> // ฟังก์ชั่นการโทรกลับ piao ' + data.tickets +' จาง - // ระบุที่อยู่ URL ของบริการ JSONP (โดยไม่คำนึงถึงประเภทของที่อยู่ค่าคืนสุดท้ายคือรหัส JavaScript) var url = "http://flightquery.com/jsonp/flightresult.aspx?code=ca1998&callback=flighthandler"; // สร้างแท็กสคริปต์และตั้งค่าแอตทริบิวต์ var script = document.createElement ('script'); script.setAttribute ('src', url); // เพิ่มแท็กสคริปต์ลงในหัวและการโทรเริ่มต้น //document.getElementsByTagname('head') [0.0.AppendChild(Script); </script> </head> <body> </body> </html> <! doctype html สาธารณะ "-// w3c // dtd xhtml 1.0 transitional // en" "http://www.w3.org/tr/xhtml1/dtd/dtd/dtd xmlns = "http://www.w3.org/1999/xhtml"> <head> <title> หน้าไม่มีชื่อ </title> <script type = "text/javascript" src = jQuery.min.js "> </script> "Get", async: false, url: "http://flightquery.com/jsonp/flightresult.aspx?code=ca1998", ประเภทข้อมูล: "jsonp", jsonp: "โทรกลับ" jsonpcallback: "Flighthandler", // ชื่อฟังก์ชั่นการโทรกลับ JSONP ที่กำหนดเอง, ค่าเริ่มต้นคือชื่อฟังก์ชั่นสุ่มที่สร้างขึ้นโดยอัตโนมัติโดย jQuery หรือคุณสามารถเขียน "?", jQuery จะประมวลผลข้อมูลโดยอัตโนมัติสำหรับคุณ: ฟังก์ชั่น (JSON) Zhang. ');มันไม่แปลกเลยเหรอ? ทำไมฉันไม่เขียนฟังก์ชั่น Flighthandler ในครั้งนี้? และมันวิ่งได้สำเร็จ! ฮ่าฮ่านี่คือเครดิตของ jQuery เมื่อ JQuery จัดการ JSONP Type AJAX (ฉันอดไม่ได้ที่จะบ่นแม้ว่า jQuery ยังจำแนก JSONP เป็น AJAX แต่จริง ๆ แล้วพวกเขาไม่ได้เป็นสิ่งเดียวกัน) มันจะสร้างฟังก์ชั่นการโทรกลับโดยอัตโนมัติและนำข้อมูลสำหรับวิธีการประสบความสำเร็จ มันไม่ดีมากเหรอ?