1. 程式人生 > >一個完整jsonp例項

一個完整jsonp例項

一個完整jsonp例項

國企車開的就是穩(màn),多了不抱怨了,說事兒。
記上次面試經歷,談到跨域,談到jsonp。因為我們開車穩,所以從不跨域。對於沒有實踐過jsonp的我來說,要是能講明白怎麼回事,就算是挺能忽悠了。但是功力低微啊,結果就是關公門前耍大刀,我覺得網上的理論知識只能讓人懂個大概。這東西不實際操作一下還是差點意思。

伺服器環境

node.js

SPA

html + jquery.js

理論知識點

json:JavaScript Object Notation是一種輕量級的資料交換格式。

優點:輕量級,易讀eval()轉化為實際的物件,傳輸階段被壓縮,易於機器解析和生成,支援多種語言。

jsonp:Json with Padding是解決跨域問題而提出的一種方案。

原理:由於瀏覽器同源策略的影響,不允許跨域的請求。而script標籤是一個特例,它的src屬性可以訪問跨域的js,利用這個特性,服務端不再返回json格式的資料,而是返回一段呼叫某個函式的js程式碼。在src中呼叫,達成跨域。

注意

  • 1.jsonp只支援GET請求。
  • 2.localhost和127.0.0.1也是跨域。
  • 3.JSONP中的"P"指什麼?
  • 4.一級域名和二級域名也算跨域。

例項解讀

客戶端

通過id="getJsonp"的按鈕動態建立script標籤,src屬性設定為跨域請求的地址,後接引數,即回撥函式jsonCallback()

function createScript(src) {
    $("<script><\/script>").attr("src",src).appendTo("body")
}
$("#getJsonp").click(function(){
    createScript("http://127.0.0.1:444/somejson?callback=jsonCallback");
});

定義回撥函式該幹嘛,這裡就直接控制檯輸出跨域請求的結果。

function jsonCallback(json) {
    console.log(json)
}

頁面所在的服務端

單純一個服務,負責模擬一個web服務。

跨域請求的服務端

對於發出跨域請求的路由,返回的內容為拼接出的一個完整的函式呼叫,這個才是關鍵。

var funcName = url.parse(req.url).query.split('&')[0].split("=")[1] // 取到請求傳入的回撥函式的名稱
	
var data = {
	"name": "MichaelMa",
	"age": 26,
	"isChild": false
}

switch (pathName){
	case "/somejson":
		res.writeHead(200, { 'content-type': 'text/plain' })
		res.write(funcName + "(" + JSON.stringify(data) + ")") // 在返回內容中拼接出一個完整的函式呼叫,效果就是jsonCallback(data)。這行程式碼是關鍵。
		break
	default:
		res.writeHead(404, { 'content-type': 'text/plain' })
		res.write("請求錯誤")
		break
}

除錯

啟動兩個服務。一個單純的web服務node serverOrigin.js,一個跨域請求的目標服務node serverDest.js。瀏覽器訪問http://localhost:333/jsonpOrigin.html ,開啟開發者工具的console項。點選按鈕頁面上get JSONP按鈕,console內輸出跨域請求的資料。

效果截圖

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

總結

至此完整的jsonp流程理順了下來,還有jquery ajax封裝的jsonp。原理也是一樣的。希望以後專案中用到時,自己能得心應手。get it!

Source Code
原blog地址