javascript
转: ajax跨域之JSONP
事件背景:
某個(gè)站點(diǎn)分為靜態(tài)產(chǎn)品介紹頁面(或由于某原因需要靜態(tài)化),和一個(gè)獨(dú)立的在線應(yīng)用程序。靜態(tài)產(chǎn)品頁面屬于www.a.com下,而在線應(yīng)用程序作為一個(gè)相對(duì)獨(dú)立的系統(tǒng)存在于app.a.com上。
在www.a.com上需要顯示在線應(yīng)用程序(app.a.com)中用戶的登錄狀態(tài)及簡(jiǎn)單的用戶信息。由于需要實(shí)時(shí)的在靜態(tài)頁面中顯示用戶登錄狀態(tài),在線應(yīng)用程序提供了一個(gè)用戶接口來輸出當(dāng)前用戶的登錄信息,靜態(tài)頁面采用ajax方式動(dòng)態(tài)獲取。
問題在于www.a.com和app.a.com分屬于不同子域,無法通過ajax直接進(jìn)行通信。~~通信協(xié)議 域名 端口號(hào)都相同才認(rèn)為是同源
思路分析:
由于同源策略的限制,XMLHttpRequest只允許請(qǐng)求當(dāng)前源(包含域名、協(xié)議、端口)的資源。
如眾周知,script標(biāo)簽經(jīng)常被用來加載不同域下的資源,例如在www.a.com可以使用http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js這個(gè)js文件,可以繞過同源策略。~~~script標(biāo)簽可以不受同源策略限制,加載不同域下的資源
同樣的,可以通過使用script標(biāo)簽來進(jìn)行跨域請(qǐng)求,但是怎么獲取異域源返回的數(shù)據(jù)呢?
有這樣一種方式:如果請(qǐng)求的這個(gè)遠(yuǎn)程數(shù)據(jù)本身就是一段可執(zhí)行的js,那么這些js會(huì)被執(zhí)行(相當(dāng)于eval)。即,若在www.a.com中存在一個(gè)showUserStatus()的js函數(shù),它的作用是在www.a.com顯示當(dāng)前用戶狀態(tài),只要給它傳遞當(dāng)前用戶的狀態(tài)數(shù)據(jù)就可以了。那么利用script標(biāo)簽請(qǐng)求的app.a.com中,輸出數(shù)據(jù)為:showUserStatus(data),那么將會(huì)執(zhí)行www.a.com中的showUserStatus(),用戶當(dāng)前的狀態(tài)就在靜態(tài)頁面上顯示了。
使用JSON來傳遞javascript對(duì)象是一種最簡(jiǎn)單的方式了,這樣的跨域通訊方式稱為JSONP。
解決方案:
1. 靜態(tài)頁面上的js:
<script type="text/javascript">function showUserStatus(data) {alert(data.txt);} </script> <!--將函數(shù)名showUserStatus傳遞過去--> <script type="text/javascript" src="http://app.a.com/userStatus.php?callback=showUserStatus"></script>2. 遠(yuǎn)程php接口:
$get = $_GET; $rtData = array('uID' => 10000,'name' => 'Zhangsf','txt' => 'Welcome ZhangSanFeng', );// 獲取傳遞來的函數(shù)名,并拼湊完整的函數(shù)執(zhí)行體 echo $get['callback'] .'('. json_encode($rtData) .')';這里輸出的格式為:
showUserStatus({"uID":10000,"name":"Zhangsf","txt":"Welcome ZhangSanFeng"})可以看出,輸出的是一個(gè)可執(zhí)行的js函數(shù)體。
總結(jié):
需要注意的是:JSONP實(shí)際上是一種腳本注入(Script Injection)方式,存在一定的安全隱患。
jQuery的書寫方法如下:
var url = 'http://app.a.com/userStatus.php?callback=?';$.getJSON(url, function(data){alert(data.txt) });抓包發(fā)現(xiàn)會(huì)產(chǎn)生類似于http://app.a.com/userStatus.php?type=json&callback=jsonp1261223089741&_=1261223089747的請(qǐng)求地址,問號(hào)被替換為一個(gè)帶時(shí)間戳的回調(diào)函數(shù)名。
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的转: ajax跨域之JSONP的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java之JVM调优案例分析与实战(1)
- 下一篇: 【javascript 变量和作用域】