JSONP解決跨域問題
- 1. 原理分析
- 1.1 同源策略
- 1.2 跨域的情形
- 1.3 跨域問題的解決方案
- 1.4 什么是JSONP
- 2. JSONP方案具體實作
- 2.1動態創建script標簽
- 2.2 用jQuery中$.getJSON()實作JSONP
- 2.3 用jQuery中$.ajax()實作JSONP
- 2.4 總結:
最近在學習ajax跨域的問題,為了加深理解,寫篇博客記錄一下,
1. 原理分析
1.1 同源策略
我們先來看看跨域問題涉及的一些概念:
- 源: 指頁面中資料的來源,由三部分指定:協議名、域名或IP地址、埠號
- 同源策略:不同源的客戶端js腳本在沒有明確授權的情況下,不能讀寫對方資源(a.com下的js腳本采用ajax不能讀取b.com里面的檔案資料,會發生跨域錯誤)
- 跨域錯誤:(如下圖)

1.2 跨域的情形

上圖中有“紅色標記”的栗子都是不同源的情形,總的來說,協議名、域名、埠號任意一項不同就不同源,
1.3 跨域問題的解決方案
- 很多專案中,為了實作前后端應用服務器分離,會特意將前端靜態資源(html/css/js等)與后臺資料介面 分處在不同的服務器上,所以域名/ip或埠號必然不相同,這就導致了“跨域請求問題”,
- 跨域問題的解決方案有:
– 代理請求
–JSONP
–CORS
…
本文主要將jsonp方案解決跨域問題,其他方案學習透徹了再來總結,
1.4 什么是JSONP
- JSONP(json with padding)是json的一種使用模式,
- 通過上面的學習,我們已經知道,由于同源策略瀏覽器會禁止JS跨域,
但是,我們知道script標簽是允許跨域請求的,利用這個特性,客戶端使用script代替XHR( XMLHttpRequest)發起跨域請求,服務器在json回應資料前后填充一些額外的內容,就稱為“填充式JSON”——JSONP
2. JSONP方案具體實作
JSONP實作跨域請求的原理就是動態創建script標簽,利用“src”不受同源策略約束的性質來實作跨域獲取資料,
菜鳥教程提供了一個鏈接,我們可以用它練練手~
鏈接:https://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction
2.1動態創建script標簽
下面栗子很簡單,就不細說了~
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONP 實體</title>
</head>
<body>
<script>
function callbackFunction(data){
console.log("i got it");
console.log(data);
}
</script>
<script>
window.onload=function(){
var script=document.createElement("script");
script.src="https://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction";
document.head.append(script);
}
</script>
</body>
</html>
2.2 用jQuery中$.getJSON()實作JSONP
- $.getJSON()方法允許通過使用JSONP形式的回呼函式來加載其他網域的JSON資料
- 使用$.getJSON()方法實作跨域請求,需要在請求路徑URL后增加callback=?, jQuery將自動替換“?”為正確的函式名,以執行回呼函式,
注:下面代碼中路徑后是jsoncallback=?,因為服務端的代碼中回呼函式名為jsoncallback,前后端應該是一致的
記得引入jQuery檔案!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONP 實體</title>
<script src="https://cdn.static.runoob.com/libs/jquery/1.8.3/jquery.js"></script>
</head>
<body>
<script>
$.getJSON("https://www.runoob.com/try/ajax/jsonp.php?jsoncallback=?",function(data){console.log(data);})
</script>
</body>
</html>
2.3 用jQuery中$.ajax()實作JSONP
$.ajax()方法同樣可以實作JSONP跨域請求,我們主要來看看它的一些選項引數:
- url:請求地址
- type:請求方式
- dataType:“jsonp” 必寫,設定服務器端回傳的資料型別,這里是"jsonp"
- jsonp:獲得jsonp回呼函式名的引數名,這個值用于代替"callback=?"(本例就是用"jsoncallback=?“代替了"callback=?”),一般默認都是callback
- jsonCallback:可選,為JSONP請求指定一個回呼函式名,這個值將代替jQuery自動生成的隨機函式名(就是代替"callback=?"中的問號)
- success:請求成功后的回呼函式,
知道這些選項引數的意思了,我們再看看上面給到的那個鏈接:
https://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction
我們看到呼叫的url中,jsoncallback引數告訴服務器,我的本地回呼函式叫做callbackFunction,讓服務器請把查詢結果傳入這個函式中,服務器傳遞給callbackFunction函式json格式的資料:callbackFunction([“customername1”,“customername2”])
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONP 實體</title>
<script src="https://cdn.static.runoob.com/libs/jquery/1.8.3/jquery.js"></script>
</head>
<body>
<script>
$.ajax({
url: "https://www.runoob.com/try/ajax/jsonp.php",
type: "get",
dataType: "jsonp",
jsonp: "jsoncallback",
success: function(data){
console.log(data);
}
})
</script>
</body>
</html>
2.4 總結:
- ajax和jsonp本質上是不同的東西,ajax的核心是通過XmlHttpRequest獲取非本頁內容,而jsonp的核心則是動態添加script標簽來呼叫服務器提供的js腳本,
- JSONP方案屬于客戶端直接請求,不存在二次請求的問題;但是,不足是script標簽只能發起get請求,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/254415.html
標籤:其他
上一篇:JavaScript作用域和閉包
下一篇:Qt撰寫地圖綜合應用27-點聚合
