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