更新時間:2023-09-28 來源:黑馬程序員 瀏覽量:
實現(xiàn)跨域數(shù)據(jù)請求,最主要的兩種解決方案,分別是 JSONP 和 CORS。
JSONP出現(xiàn)的早,兼容性好(兼容低版本IE)。是前端程序員為了解決跨域問題,被迫想出來的一種臨時解決方案。缺點是只支持 GET 請求,不支持 POST 請求。
CORS出現(xiàn)的較晚,它是 W3C 標準,屬于跨域 Ajax 請求的根本解決方案。支持 GET 和 POST 請求。缺點是不兼容某些低版本的瀏覽器。
本節(jié)先來看JSONP解決跨域問題的原理和方法。
由于瀏覽器同源策略的限制,網(wǎng)頁中無法通過 Ajax 請求非同源的接口數(shù)據(jù)。但是<script> 標簽不受瀏覽器同源策略的影響,可以通過 src 屬性,請求非同源的 js 腳本。
因此,JSONP 的實現(xiàn)原理,就是通過<script> 標簽的 src 屬性,請求跨域的數(shù)據(jù)接口,并通過函數(shù)調(diào)用的形式,接收跨域接口響應回來的數(shù)據(jù)。
定義一個 success 回調(diào)函數(shù):
<script> function success(data) { console.log('獲取到了data數(shù)據(jù):') console.log(data) } </script>
通過 <script>標簽,請求接口數(shù)據(jù):
<script src="http://ajax.frontend.itheima.net:3006/api/jsonp?callback=success&name=zs &age=20"></script>
注意:JSONP 和 Ajax 之間沒有任何關(guān)系,不能把 JSONP 請求數(shù)據(jù)的方式叫做 Ajax,因為 JSONP 沒有用到 XMLHttpRequest 這個對象。
jQuery 提供的 $.ajax() 函數(shù),除了可以發(fā)起真正的 Ajax 數(shù)據(jù)請求之外,還能夠發(fā)起 JSONP 數(shù)據(jù)請求,例如:
$.ajax({ url: 'http://ajax.frontend.itheima.net:3006/api/jsonp?name=zs&age=20', // 如果要使用 $.ajax() 發(fā)起 JSONP 請求,必須指定 datatype 為 jsonp dataType: 'jsonp', success: function(res) { console.log(res) } })
默認情況下,使用 jQuery 發(fā)起 JSONP 請求,會自動攜帶一個 callback=jQueryxxx 的參數(shù),jQueryxxx 是隨機生成的一個回調(diào)函數(shù)名稱。
在使用 jQuery 發(fā)起 JSONP 請求時,如果想要自定義 JSONP 的參數(shù)以及回調(diào)函數(shù)名稱,可以通過如下兩個參數(shù)來指定:
$.ajax({ url: 'http://ajax.frontend.itheima.net:3006/api/jsonp?name=zs&age=20', dataType: 'jsonp', // 發(fā)送到服務端的參數(shù)名稱,默認值為 callback jsonp: 'callback', // 自定義的回調(diào)函數(shù)名稱,默認值為 jQueryxxx 格式 jsonpCallback: 'abc', success: function(res) { console.log(res) } })
jQuery 中的 JSONP,也是通過<script> 標簽的 src 屬性實現(xiàn)跨域數(shù)據(jù)訪問的,只不過,jQuery 采用的是動態(tài)創(chuàng)建和移除<script>標簽的方式,來發(fā)起 JSONP 數(shù)據(jù)請求。
在發(fā)起 JSONP 請求的時候,動態(tài)向<script> 中 append 一個<script> 標簽;
在 JSONP 請求成功以后,動態(tài)從<script> 中移除剛才 append 進去的<script> 標簽;