網(wǎng)站日程建設(shè)表百度在線客服問答
前言 | ?? 不管前方的路多么崎嶇不平,只要走的方向正確,都比站在原地更接近幸福 ?? |
---|
Ajax進(jìn)階篇02---跨域與JSONP
- 一、Ajax進(jìn)階篇02---跨域與JSONP
- (1)同源策略
- 1.1 什么是同源
- 1.2 什么是同源策略
- (2)跨域
- 2.1 什么是跨域
- 2.2 瀏覽器對跨域請求的攔截
- 2.3 如何實現(xiàn)跨域數(shù)據(jù)請求
- (3)JSONP
- 3.1 什么是JSONP
- 3.2 JSONP的實現(xiàn)原理
- 3.3 JSONP的缺點
- 3.4 jQuery中的JSONP
- 3.5 自定義參數(shù)及回調(diào)函數(shù)名稱
- 3.6 jQuery中JSONP的實現(xiàn)過程
- (4)防抖
- 4.1 什么是防抖
- 4.2 防抖的應(yīng)用場景
- (5)節(jié)流
- 5.1 什么是節(jié)流
- 5.2 節(jié)流的應(yīng)用場景
- 5.3 節(jié)流閥的概念
- 5.3 節(jié)流案例 – 鼠標(biāo)跟隨效果
- (6)總結(jié)防抖和節(jié)流的區(qū)別
- 二、總結(jié)
一、Ajax進(jìn)階篇02—跨域與JSONP
(1)同源策略
1.1 什么是同源
如果兩個頁面的協(xié)議,域名和端口都相同,則兩個頁面具有相同的源。
例如,下表給出了相對于 http://www.test.com/index.html 頁面的同源檢測:
URL | 是否同源 | 原因 |
---|---|---|
http://www.test.com/other.html | 是 | 同源(協(xié)議、域名、端口相同) |
https://www.test.com/about.html | 否 | 協(xié)議不同(http 與 https) |
http://blog.test.com/movie.html | 否 | 域名不同(www.test.com 與 blog.test.com) |
http://www.test.com:7001/home.html | 否 | 端口不同(默認(rèn)的 80 端口與 7001 端口) |
http://www.test.com:80/main.html | 是 | 同源(協(xié)議、域名、端口相同) |
1.2 什么是同源策略
1?? 同源策略(英文全稱 Same origin policy)是瀏覽器提供的一個安全功能;
2?? MDN 官方給定的概念:同源策略限制了從同一個源加載的文檔或腳本如何與來自另一個源的資源進(jìn)行交互。這是一個用于隔離潛在惡意文件的重要安全機制;
3?? 通俗的理解:瀏覽器規(guī)定,A 網(wǎng)站的 JavaScript,不允許和非同源的網(wǎng)站 C 之間,進(jìn)行資源的交互,例如:
- 無法讀取非同源網(wǎng)頁的 Cookie、LocalStorage 和 IndexedDB;
- 無法接觸非同源網(wǎng)頁的 DOM;
- 無法向非同源地址發(fā)送 Ajax 請求;
(2)跨域
2.1 什么是跨域
同源指的是兩個 URL 的協(xié)議、域名、端口一致,反之,則是跨域。
出現(xiàn)跨域的根本原因:瀏覽器的同源策略不允許非同源的 URL 之間進(jìn)行資源的交互;
2.2 瀏覽器對跨域請求的攔截

😆溫馨提醒😆:瀏覽器允許發(fā)起跨域請求,但是,跨域請求回來的數(shù)據(jù),會被瀏覽器攔截,無法被頁面獲取到!
2.3 如何實現(xiàn)跨域數(shù)據(jù)請求
1?? 現(xiàn)如今,實現(xiàn)跨域數(shù)據(jù)請求,最主要的兩種解決方案,分別是 JSONP
和 CORS
;
2?? JSONP
:出現(xiàn)的早,兼容性好(兼容低版本IE)。是前端程序員為了解決跨域問題,被迫想出來的一種臨時解決方案。缺點是只支持 GET 請求,不支持 POST 請求;
3?? CORS
:出現(xiàn)的較晚,它是 W3C 標(biāo)準(zhǔn),屬于跨域 Ajax 請求的根本解決方案。支持 GET 和 POST 請求。缺點是不兼容某些低版本的瀏覽器;
(3)JSONP
3.1 什么是JSONP
JSONP
(JSON with Padding) 是 JSON 的一種“使用模式”,可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問的問題
3.2 JSONP的實現(xiàn)原理
1?? 由于瀏覽器同源策略的限制,網(wǎng)頁中無法通過 Ajax 請求非同源的接口數(shù)據(jù)。但是 <script>
標(biāo)簽不受瀏覽器同源策略的影響,可以通過 src 屬性,請求非同源的 js 腳本。
2?? 因此,JSONP 的實現(xiàn)原理,就是通過 <script>
標(biāo)簽的 src 屬性,請求跨域的數(shù)據(jù)接口,并通過函數(shù)調(diào)用的形式,接收跨域接口響應(yīng)回來的數(shù)據(jù)。
3.3 JSONP的缺點
由于 JSONP 是通過 <script>
標(biāo)簽的 src 屬性,來實現(xiàn)跨域數(shù)據(jù)獲取的,所以,JSONP 只支持 GET 數(shù)據(jù)請求,不支持 POST 請求。
😆溫馨提醒😆:JSONP 和 Ajax 之間沒有任何關(guān)系,不能把 JSONP 請求數(shù)據(jù)的方式叫做 Ajax,因為 JSONP 沒有用到 XMLHttpRequest 這個對象。
3.4 jQuery中的JSONP
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 為 jsonpdataType: 'jsonp',success: function(res) {console.log(res)}
})
😆溫馨提醒😆:默認(rèn)情況下,使用 jQuery 發(fā)起 JSONP 請求,會自動攜帶一個 callback=jQueryxxx
的參數(shù),jQueryxxx 是隨機生成的一個回調(diào)函數(shù)名稱。
3.5 自定義參數(shù)及回調(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ā)送到服務(wù)端的參數(shù)名稱,默認(rèn)值為 callbackjsonp: 'callback',// 自定義的回調(diào)函數(shù)名稱,默認(rèn)值為 jQueryxxx 格式jsonpCallback: 'abc',success: function(res) {console.log(res)}
})
3.6 jQuery中JSONP的實現(xiàn)過程
jQuery 中的 JSONP,也是通過 <script>
標(biāo)簽的 src 屬性實現(xiàn)跨域數(shù)據(jù)訪問的,只不過,jQuery 采用的是動態(tài)創(chuàng)建和移除 <script>
標(biāo)簽的方式,來發(fā)起 JSONP 數(shù)據(jù)請求。
- 在發(fā)起 JSONP 請求的時候,動態(tài)向
<header
> 中 append 一個<script>
標(biāo)簽; - 在 JSONP 請求成功以后,動態(tài)從
<header>
中移除剛才 append 進(jìn)去的<script>
標(biāo)簽;
(4)防抖
4.1 什么是防抖
防抖策略(debounce)是當(dāng)事件被觸發(fā)后,延遲 n 秒后再執(zhí)行回調(diào),如果在這 n 秒內(nèi)事件又被觸發(fā),則重新計時;
4.2 防抖的應(yīng)用場景
用戶在輸入框中連續(xù)輸入一串字符時,可以通過防抖策略,只在輸入完后,才執(zhí)行查詢的請求,這樣可以有效減少請求次數(shù),節(jié)約請求資源;
實現(xiàn)輸入框的防抖:
var timer = null; // 1. 防抖動的 timerfunction debounceSearch(keywords) { // 2. 定義防抖的函數(shù)timer = setTimeout(function() {// 發(fā)起 JSONP 請求getSuggestList(keywords)}, 500)
}$('#ipt').on('keyup', function() { // 3. 在觸發(fā) keyup 事件時,立即清空 timerclearTimeout(timer)// ...省略其他代碼debounceSearch(keywords)
})
(5)節(jié)流
5.1 什么是節(jié)流
節(jié)流就是指連續(xù)觸發(fā)事件但是在 n 秒中只執(zhí)行一次函數(shù)。節(jié)流會稀釋函數(shù)的執(zhí)行頻率;
5.2 節(jié)流的應(yīng)用場景
- 鼠標(biāo)連續(xù)不斷地觸發(fā)某事件(如點擊),只在單位時間內(nèi)只觸發(fā)一次;
- 懶加載時要監(jiān)聽計算滾動條的位置,但不必每次滑動都觸發(fā),可以降低計算的頻率,而不必去浪費 CPU 資源;
5.3 節(jié)流閥的概念
1?? 節(jié)流閥為空,表示可以執(zhí)行下次操作;不為空,表示不能執(zhí)行下次操作;
2?? 當(dāng)前操作執(zhí)行完,必須將節(jié)流閥重置為空,表示可以執(zhí)行下次操作了;
3?? 每次執(zhí)行操作前,必須先判斷節(jié)流閥是否為空;
5.3 節(jié)流案例 – 鼠標(biāo)跟隨效果
案例素材:
完整代碼演示如下:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="./lib/jquery.js"></script><style>/* CSS 樣式 */html,body {margin: 0;padding: 0;overflow: hidden;}#angel {position: absolute;}</style>
</head><body><!-- UI 結(jié)構(gòu) --><img src="./angel.gif" alt="" id="angel" /><script>$(function () {// 1. 獲取到圖片var angel = $('#angel')// 步驟1. 定義節(jié)流閥var timer = null;// 2. 綁定 mousemove 事件$(document).on('mousemove', function (e) {// 步驟3:判斷節(jié)流閥是否為空, 如果不為空, 則證明距離上次執(zhí)行間隔不足16毫秒if (timer) { return }// 3. 設(shè)置圖片的位置// 步驟2:開啟延時器timer = setTimeout(function () {$(angel).css('top', e.pageY + 'px').css('left', e.pageX + 'px')console.log('ok')// 當(dāng)設(shè)置了鼠標(biāo)跟隨效果后,清空 timer 節(jié)流閥,方便下次開啟延時器timer = null}, 16)})})</script>
</body></html>
(6)總結(jié)防抖和節(jié)流的區(qū)別
- 防抖:如果事件被頻繁觸發(fā),防抖能保證只有最后一次觸發(fā)生效,前面 N 多次的觸發(fā)都會被忽略;
- 節(jié)流:如果事件被頻繁觸發(fā),節(jié)流能夠減少事件觸發(fā)的頻率,因此,節(jié)流是有選擇性地執(zhí)行一部分事件;
二、總結(jié)
😝 由于內(nèi)容較多,所以我決定分開寫啦,我會堅持一直更新呢!喜歡的朋友們記得點點贊哦! 😝