javascript
ajax datatype_JavaScript学习笔记(二十七) ajax及ajax封装
AJAX
ajax 全名 async javascript and XML
是前后臺交互的能力
也就是我們客戶端給服務端發送消息的工具,以及接受響應的工具
是一個 默認異步 執行機制的功能
AJAX 的優勢
不需要插件的支持,原生 js 就可以使用
用戶體驗好(不需要刷新頁面就可以更新數據)
減輕服務端和帶寬的負擔
缺點:搜索引擎的支持度不夠,因為數據都不在頁面上,搜索引擎搜索不到
AJAX 的使用
在 js 中有內置的構造函數來創建 ajax 對象
創建 ajax 對象以后,我們就使用 ajax 對象的方法去發送請求和接受響應
創建一個 ajax 對象
// IE9及以上const xhr = new XMLHttpRequest()// IE9以下const xhr = new ActiveXObject('Mricosoft.XMLHTTP')上面就是有了一個 ajax 對象
我們就可以使用這個 xhr 對象來發送 ajax 請求了
配置鏈接信息
const xhr = new XMLHttpRequest()// xhr 對象中的 open 方法是來配置請求信息的// 第一個參數是本次請求的請求方式 get / post / put / ...// 第二個參數是本次請求的 url // 第三個參數是本次請求是否異步,默認 true 表示異步,false 表示同步// xhr.open('請求方式', '請求地址', 是否異步)xhr.open('get', './data.php')上面的代碼執行完畢以后,本次請求的基本配置信息就寫完了
發送請求
const xhr = new XMLHttpRequest()xhr.open('get', './data.php')// 使用 xhr 對象中的 send 方法來發送請求xhr.send()上面代碼是把配置好信息的 ajax 對象發送到服務端
一個基本的 ajax 請求
一個最基本的 ajax 請求就是上面三步
但是光有上面的三個步驟,我們確實能把請求發送的到服務端
如果服務端正常的話,響應也能回到客戶端
但是我們拿不到響應
如果想拿到響應,我們有兩個前提條件
本次 HTTP 請求是成功的,也就是我們之前說的 http 狀態碼為 200 ~ 299
ajax 對象也有自己的狀態碼,用來表示本次 ajax 請求中各個階段
ajax 狀態碼
ajax 狀態碼 - xhr.readyState
是用來表示一個 ajax 請求的全部過程中的某一個狀態
readyState === 0:表示未初始化完成,也就是 open 方法還沒有執行
readyState === 1:表示配置信息已經完成,也就是執行完 open 之后
readyState === 2:表示 send 方法已經執行完成
readyState === 3:表示正在解析響應內容
readyState === 4:表示響應內容已經解析完畢,可以在客戶端使用了
這個時候我們就會發現,當一個 ajax 請求的全部過程中,只有當 readyState === 4 的時候,我們才可以正常使用服務端給我們的數據
所以,配合 http 狀態碼為 200 ~ 299
一個 ajax 對象中有一個成員叫做 xhr.status
這個成員就是記錄本次請求的 http 狀態碼的
兩個條件都滿足的時候,才是本次請求正常完成
readyStateChange
在 ajax 對象中有一個事件,叫做 readyStateChange 事件
這個事件是專門用來監聽 ajax 對象的 readyState 值改變的的行為
也就是說只要 readyState 的值發生變化了,那么就會觸發該事件
所以我們就在這個事件中來監聽 ajax 的 readyState 是不是到 4 了
responseText
ajax 對象中的 responseText 成員
就是用來記錄服務端給我們的響應體內容的
所以我們就用這個成員來獲取響應體內容就可以
使用 ajax 發送請求時攜帶參數
我們使用 ajax 發送請求也是可以攜帶參數的
參數就是和后臺交互的時候給他的一些信息
但是攜帶參數 get 和 post 兩個方式還是有區別的
發送一個帶有參數的 get 請求
get 請求的參數就直接在 url 后面進行拼接就可以
這樣服務端就能接受到兩個參數
一個是 a,值是 100
一個是 b,值是 200
發送一個帶有參數的 post 請求
post 請求的參數是攜帶在請求體中的,所以不需要再 url 后面拼接
application/x-www-form-urlencoded 表示的數據格式就是 key=value&key=value
同源策略
同源策略是由瀏覽器給的
瀏覽器不允許我們向別人發送請求,只能向自己的服務器發送請求
當我們想向別人的服務器發送請求的時候,就會被瀏覽器阻止了
什么是 “別人的服務器” 呢?
當 請求協議/域名/端口號 有任意一個不同的時候,那么就算是別人的服務器
這個時候就會觸發同源策略
我們管觸發了 同源策略 的請求叫做跨域請求
實現一個跨域請求
有的時候我們是需要實現跨域請求的
我們需要多個服務器給一個頁面提供數據
那么這個時候我們就要想辦法解決跨域問題
JSONP
jsonp 是我們實現跨域請求的手段,是把我們之前的東西組合在一起使用的技術手段而已
利用的是 script 標簽來實現
script 標簽的本質
瀏覽器給我們提供了一個 script 標簽
它的本質就是請求一個外部資源,是不受到同源策略的影響的
同時 script 標簽的 src 屬性,也是一種請求,也能被服務器接收到
并且:
script標簽的src屬性請求回來的東西是一個字符串,瀏覽器會把這個字符串當作 js 代碼來執行
所以我們就可以利用這個 script 標簽的 src 屬性來進行跨域請求了
配置代理(了解)
代理,分成兩種,正向代理和反向代理
正向代理
有一個客戶端需要向一個非同源的服務器B發送請求
我們搭建一個和客戶端同源的服務器A
當客戶端發送請求的時候,由服務器A來接受
再由服務器A向服務器B發送請求,因為 同源策略是由瀏覽器給的,服務器之間沒有
服務器B接受到請求以后,會處理請求,并把響應返回給服務器A
再由服務器A把響應給到客戶端就可以了
我們就可以用這個方式來進行跨域請求了
反向代理
反向代理一般是用來做負載均衡的
當我請求一個服務器的時候,其實請求的是服務器端設置的代理服務器
由代理服務器把若干大量的請求分發給不同的服務器進行處理
再由服務器把響應給到代理服務器
代理服務器返回給客戶端
封裝 AJAX
ajax 使用起來太麻煩,因為每次都要寫很多的代碼
那么我們就封裝一個 ajax 方法來讓我們使用起來簡單一些
確定一下使用的方式
因為有一些內容可以不傳遞,我們可以使用默認值,所以選擇對象傳遞參數的方式// 使用的時候直接調用,傳遞一個對象就可以ajax({url: '', // 請求的地址type: '', // 請求方式async: '', // 是否異步data: '', // 攜帶的參數dataType: '', // 要不要執行 json.parsesuccess: function () {} // 成功以后執行的函數})
確定好使用方式以后,就開始書寫封裝函數
封裝
function ajax(options) { // 先準備一個默認值 var defInfo = { url: '', // 地址不需要默認值 type: 'GET', // 請求方式的默認值是 GET async: false, // 默認值是異步 data: '', // 參數沒有默認值 dataType: 'string', // 默認不需要執行 json.parse success () {}, // 默認是一個函數} // 先來判斷一下有沒有傳遞 url,如果沒有,直接拋出異常 if (!options.url) { throw new Error('url 必須傳遞')} // 有了 url 以后就,我們就把用戶傳遞的參數和我們的默認數據合并 for (let key in options) { defInfo[key] = options[key]} // 接下來的一切我們都是使用我們的 defInfo 就可以了 // 第一步就是判斷參數 data // data 可以不傳遞,可以為空 // data 也可以是一個 key=value&key=value 格式的字符串 // data 也可以是一個對象 // 否則就拋出異常 if (!(typeof defInfo.data === 'string' && /^(\w+=\w+&?)*$/.test(defInfo.data) || Object.prototype.toString.call(defInfo.data) === '[object Object]')) { throw new Error('請按照要求傳遞參數')} // 參數處理完畢以后,在判斷 async 的數據類型 // 只能傳遞 布爾數據類型 if (typeof defInfo.async !== 'boolean') { throw new Error('async 參數只接受布爾數據類型')} // 在接下來就判斷 type // 請求方式我們只接受 GET 或著 POST if (!(defInfo.type.toUpperCase() === 'GET' || defInfo.type.toUpperCase() === 'POST')) { throw new Error('目前本插件只接受 GET 和 POST 方式,請期待更新')} // 接下來就是判斷 success 的判斷,必須是一個函數 if (Object.prototype.toString.call(defInfo.success) !== '[object Function]') { throw new Error('success 只接受函數數據類型')} // 參數都沒有問題了 // 我們就要把 data 處理一下了 // 因為 data 有可能是對象,當 data 是一個對象的時候,我們要把它轉換成一個字符串 var str = '' if (Object.prototype.toString.call(defInfo.data) === '[object Object]') { for (let attr in defInfo.data) { str += `${attr}=${defInfo.data[attr]}&` } str = str.slice(0, -1) defInfo.data = str} // 參數全部驗證過了以后,我們就可以開始進行正常的 ajax 請求了 // 1. 準備一個 ajax 對象 // 因為要處理兼容問題,所以我們準備一個函數 function createXHR() { if (XMLHttpRequest) { return new XMLHttpRequest() } else { return new ActiveXObject('Microsoft.XMLHTTP') }} // 2. 創建一個 ajax 對象 var xhr = createXHR() // 3. 進行 open xhr.open(defInfo.type, defInfo.url + (defInfo.type.toUpperCase() === 'GET' ? `?${defInfo.data}&_=${new Date().getTime()}` : ''), defInfo.async) if (defInfo.type.toUpperCase() === 'POST') { xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')} // 4. 進行 send xhr.send((defInfo.type.toUpperCase() === 'POST' ? `${defInfo.data}` : '')) // 5. 接受響應 xhr.onreadystatechange = function () { if (xhr.readyState === 4 && /2\d{2}/.test(xhr.status)) { // 表示成功,我們就要執行 success // 但是要進行 dataType 的判斷 if (defInfo.dataType === 'json') { defInfo.success(JSON.parse(xhr.responseText)) } else { defInfo.success() } }}}?苦逼的日子,有你真好看見這個分享了嗎,點它總結
以上是生活随笔為你收集整理的ajax datatype_JavaScript学习笔记(二十七) ajax及ajax封装的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows To Ghost系统封装
- 下一篇: 雷林鹏分享:codeigniter框架文