跨越跨域大山,前端不得不知道的Ajax
AJAX和跨域
- 引言
- 正文
- 一、AJAX請求
- 1、模擬get和post請求
- 2、封裝一個簡易的AJAX
- 二、狀態碼
- 1、xhr.readyState
- 2、xhr.status
- 三、跨域
- 1、同源策略
- (1)同源策略是什么
- (2)為什么瀏覽器會有同源策略?
- (3)同源策略限制內容有哪些?
- (4)加載圖片、js和css時可以無視同源策略
- 2、跨域解決方案
- (1)跨域是什么
- (2)解決跨域的方式
- 1)JSONP(客戶端操作)
- 2)CORS(服務器操作)
- 結束語
引言
ajax對于前端來說是一個特別基礎也特別實用的一個功能,基本上我們目前訪問的很多網頁都有用到 ajax 的功能。接下來開始講解關于AJAX請求,以及關于跨域的一些內容。
正文
一、AJAX請求
Ajax ,即 Asynchronous Javascript And XML(異步JavaScript和XML)。
在實現 Ajax 之前,我們先來了解下 XMLHttpRequest 。 XMLHttpRequest 是網頁實現 AJAX 最主要的一個 API 。可能有很多同學知道 AJAX ,也用過 AJAX ,但是卻不知道它是基于 XMLHttpRequest 來實現的。
那么接下來我們用 XMLHttpRequest 這個 API 來模擬一個 get 和 post 請求。
1、模擬get和post請求
(1)模擬get請求:
/*** 使用xhr模擬實現GET請求*/ const xhr = new XMLHttpRequest(); xhr.open('GET', '/test.json', true); //false表示同步請求,true表示異步請求 xhr.onreadystatechange = function () {// 這里的函數異步執行if(xhr.readyState === 4){if(xhr.status === 200){// console.log(// JSON.parse(xhr.responseText)// );alert(xhr.responseText);}} } // 因為是get請求,所以只要發送null就好 xhr.send(null);(2)模擬post請求:
/*** 使用xhr模擬實現post請求*/ const xhr = new XMLHttpRequest(); //模擬請求一個登錄接口 xhr.open('POST', '/login', true); //false表示同步請求,true表示異步請求 xhr.onreadystatechange = function(){if(xhr.readyState === 4){if(xhr.status === 200){console.log(JSON.parse(xhr.responseText));alert(xhr.responseText);}else{console.log('其他情況');}} }const postData = {userName: 'zhangsan',password: 'xxx' }xhr.send(JSON.stringify(postData));2、封裝一個簡易的AJAX
function ajax(url){const p = new Promise((resolve, reject) => {const xhr = new XMLHttpRequest();xhr.open('GET', url, true);xhr.onreadystatechange = function(){//狀態碼的解析詳細看第二點if(xhr.readyState === 4){if(xhr.status === 200){resolve(JSON.parse(xhr.responseText));}else if(xhr.status === 404){reject(new Error('404 not found'));}}}xhr.send(null);});return p; }const url = '你的json數據路徑'; ajax(url) .then(res => console.log(res)) .catch(err => console.error(err));二、狀態碼
看完上面的模擬過程之后,我們來講解其中的幾個知識點。
1、xhr.readyState
| 0 | (未初始化)- 還沒有調用send()方法 |
| 1 | (載入)- 已調用send()方法,正坐在發送請求 |
| 2 | (載入完成)- send()方法執行完成,已經接收到全部響應內容 |
| 3 | (交互)- 正在解析響應內容 |
| 4 | (完成)響應內容解析完成,可以在客戶端調用 |
2、xhr.status
| 2xx | 表示成功處理請求,如200 |
| 3xx | 需要重定向,瀏覽器直接跳轉,如301 302 304 |
| 4xx | 客戶端請求錯誤,如404 403 |
| 5xx | 服務器端錯誤 |
三、跨域
1、同源策略
(1)同源策略是什么
同源策略是瀏覽器自帶的一種安全策略,它是指網址中的協議、域名、端口三個都相同時才能互相訪問,即若協議、域名、端口有一個不相同時,瀏覽器禁止頁面加載或執行與自身不同域的腳本。
(2)為什么瀏覽器會有同源策略?
因為如果沒有同源策略,別人就可以輕松的獲取我們網站的 cookie 信息,或是對網頁進行 DOM 操作;
這是一件非常恐怖的事情,尤其是 cookie 信息,它里面存在著 sessionID ,這是與服務端的 session 會話的重要憑證,如果被別人得到了 cookie ,有很大可能會造成數據被盜取等后果。
(3)同源策略限制內容有哪些?
- 存儲在瀏覽器中的數據,如 localStroage 、 Cookie 和 IndexedDB 不能通過腳本跨域訪問;
- 不能通過腳本操作不同域下的 DOM ;
- 不能通過 ajax 請求不同域的數據。
(4)加載圖片、js和css時可以無視同源策略
<img src = 跨域的圖片地址 /> <link href = 跨域的css地址/> <script src = 跨域的js地址></script>如以上代碼所示,當我們在加載以上類型的 圖片、css和js 時,可以無視同源策略。因為像 圖片、css文件和js文件 一般可使用 cdn 來進行緩存,而 cdn 一般是外域。同時, js 文件也可以通過 JSONP 來實現跨域。
2、跨域解決方案
(1)跨域是什么
- 所有的跨域,都必須經過 server 端允許和配合;
- 未經 server 端允許就實現跨域,說明瀏覽器有漏洞,是一種危險信號。
(2)解決跨域的方式
1)JSONP(客戶端操作)
① JSONP的原理
JSONP(JSON with Padding)是數據格式 JSON 的一種“使用模式”,可以讓網頁從別的網域要數據。
根據 XmlHttpRequest 對象受到同源策略的影響,而利用
用 JSONP 抓到的數據并不是 JSON ,而是任意的 JavaScript ,用 JavaScript 解釋器運行而不是用 JSON 解析器解析。
所以,通過 Chrome 查看所有 JSONP 發送的 Get 請求都是 js 類型,而非 XHR 。
② JSONP包含兩部分:回調函數和數據
回調函數是當響應到來時要放在當前頁面被調用的函數。
數據就是傳入回調函數中的 json 數據,也就是回調函數的參數了。
function handleResponse(response){console.log('The responsed data is: '+response.data); } var script = document.createElement('script'); script.src = 'http://www.baidu.com/json/?callback=handleResponse'; document.body.insertBefore(script, document.body.firstChild); /*handleResonse({"data": "zhe"})*/ //原理如下: //當我們通過script標簽請求時 //后臺就會根據相應的參數(json,handleResponse) //來生成相應的json數據(handleResponse({"data": "zhe"})) //最后這個返回的json數據(代碼)就會被放在當前js文件中被執行 //至此跨域通信完成③ 缺點:
- 只能使用Get請求。
- 不能注冊success、error等事件監聽函數,不能很容易的確定 JSONP 請求是否失敗。
- JSONP 是從其他域中加載代碼執行,容易受到跨站請求偽造的攻擊,其安全性無法確保。
2)CORS(服務器操作)
① cors的原理
CORS (Cross-Origin Resource Sharing),即跨域資源共享,是一種瀏覽器技術的規范,提供了 Web 服務從不同域傳來沙盒腳本的方法,以避開瀏覽器的同源策略,確保安全的跨域數據傳輸。現代瀏覽器使用 CORS 在 API 容器如 XMLHttpRequest 來減少 HTTP 請求的風險來源。與 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。
② cors 的跨域方法一般是服務端進行操作,服務端需要設置以下 http header :
//設置允許跨域的域名稱,不建議直接寫“*” response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080");//填寫允許跨域的http請求方法 //當 method = OPTIONS 時, 屬于預檢(復雜請求), 當為預檢時, 可以直接返回空響應體, 對應的 http 狀態碼為 204 response.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");//設置需要支持的跨域請求頭,如果設置為*,表明服務器支持所有頭信息字段;也可設置為X-Request-With和Content-Type response.setHeader("Access-Control-Allow-Headers", "X-Request-With, Content-Type"); // 服務器收到請求以后,檢查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,確認允許跨源請求,就可以做出回應。//表示具體請求中的媒體類型信息 response.setHeader("Content-Type", "application/json;charset=utf-8");//設置預檢結果的緩存, 單位(秒) response.setHeader("Access-Control-Max-Age", 86400);/*如果需要支持 cookies,*Access-Control-Allow-Origin 不能設置為 *,*并且 Access-Control-Allow-Credentials 需要設置為 true*(注意前端請求需要設置 withCredentials = true) */ response.setHeader("Access-Control-Allow-Credentials", "false");結束語
以上文章淺談了 ajax 以及常用的跨域方案,沒有深究到很細節層面的內容。希望對大家有幫助!
關于Ajax以及跨域的一些信息就講到這里啦!如有疑問歡迎評論區評論或私信我交流~
-
關注公眾號 星期一研究室 ,不定期分享學習干貨
-
如果這篇文章對你有用,記得點個贊加個關注再走哦~
總結
以上是生活随笔為你收集整理的跨越跨域大山,前端不得不知道的Ajax的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windows桌面管理软件(怎么管理电脑
- 下一篇: Word中如何制作目录