日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

ajax datatype_JavaScript学习笔记(二十七) ajax及ajax封装

發(fā)布時(shí)間:2023/12/19 javascript 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ajax datatype_JavaScript学习笔记(二十七) ajax及ajax封装 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

AJAX

  • ajax 全名 async javascript and XML

  • 是前后臺(tái)交互的能力

  • 也就是我們客戶端給服務(wù)端發(fā)送消息的工具,以及接受響應(yīng)的工具

  • 是一個(gè) 默認(rèn)異步 執(zhí)行機(jī)制的功能

AJAX 的優(yōu)勢(shì)

  • 不需要插件的支持,原生 js 就可以使用

  • 用戶體驗(yàn)好(不需要刷新頁面就可以更新數(shù)據(jù))

  • 減輕服務(wù)端和帶寬的負(fù)擔(dān)

  • 缺點(diǎn):搜索引擎的支持度不夠,因?yàn)閿?shù)據(jù)都不在頁面上,搜索引擎搜索不到

  • AJAX 的使用

    • 在 js 中有內(nèi)置的構(gòu)造函數(shù)來創(chuàng)建 ajax 對(duì)象

    • 創(chuàng)建 ajax 對(duì)象以后,我們就使用 ajax 對(duì)象的方法去發(fā)送請(qǐng)求和接受響應(yīng)

    創(chuàng)建一個(gè) ajax 對(duì)象

    // IE9及以上const xhr = new XMLHttpRequest()// IE9以下const xhr = new ActiveXObject('Mricosoft.XMLHTTP')
    • 上面就是有了一個(gè) ajax 對(duì)象

    • 我們就可以使用這個(gè) xhr 對(duì)象來發(fā)送 ajax 請(qǐng)求了

    配置鏈接信息

    const xhr = new XMLHttpRequest()// xhr 對(duì)象中的 open 方法是來配置請(qǐng)求信息的// 第一個(gè)參數(shù)是本次請(qǐng)求的請(qǐng)求方式 get / post / put / ...// 第二個(gè)參數(shù)是本次請(qǐng)求的 url // 第三個(gè)參數(shù)是本次請(qǐng)求是否異步,默認(rèn) true 表示異步,false 表示同步// xhr.open('請(qǐng)求方式', '請(qǐng)求地址', 是否異步)xhr.open('get', './data.php')
    • 上面的代碼執(zhí)行完畢以后,本次請(qǐng)求的基本配置信息就寫完了

    發(fā)送請(qǐng)求

    const xhr = new XMLHttpRequest()xhr.open('get', './data.php')// 使用 xhr 對(duì)象中的 send 方法來發(fā)送請(qǐng)求xhr.send()
    • 上面代碼是把配置好信息的 ajax 對(duì)象發(fā)送到服務(wù)端

    一個(gè)基本的 ajax 請(qǐng)求

    • 一個(gè)最基本的 ajax 請(qǐng)求就是上面三步

    • 但是光有上面的三個(gè)步驟,我們確實(shí)能把請(qǐng)求發(fā)送的到服務(wù)端

    • 如果服務(wù)端正常的話,響應(yīng)也能回到客戶端

    • 但是我們拿不到響應(yīng)

    • 如果想拿到響應(yīng),我們有兩個(gè)前提條件

  • 本次 HTTP 請(qǐng)求是成功的,也就是我們之前說的 http 狀態(tài)碼為 200 ~ 299

  • ajax 對(duì)象也有自己的狀態(tài)碼,用來表示本次 ajax 請(qǐng)求中各個(gè)階段

  • ajax 狀態(tài)碼

    • ajax 狀態(tài)碼 - xhr.readyState

    • 是用來表示一個(gè) ajax 請(qǐng)求的全部過程中的某一個(gè)狀態(tài)

      • readyState === 0:表示未初始化完成,也就是 open 方法還沒有執(zhí)行

      • readyState === 1:表示配置信息已經(jīng)完成,也就是執(zhí)行完 open 之后

      • readyState === 2:表示 send 方法已經(jīng)執(zhí)行完成

      • readyState === 3:表示正在解析響應(yīng)內(nèi)容

      • readyState === 4:表示響應(yīng)內(nèi)容已經(jīng)解析完畢,可以在客戶端使用了

    • 這個(gè)時(shí)候我們就會(huì)發(fā)現(xiàn),當(dāng)一個(gè) ajax 請(qǐng)求的全部過程中,只有當(dāng) readyState === 4 的時(shí)候,我們才可以正常使用服務(wù)端給我們的數(shù)據(jù)

    • 所以,配合 http 狀態(tài)碼為 200 ~ 299

      • 一個(gè) ajax 對(duì)象中有一個(gè)成員叫做 xhr.status

      • 這個(gè)成員就是記錄本次請(qǐng)求的 http 狀態(tài)碼的

    • 兩個(gè)條件都滿足的時(shí)候,才是本次請(qǐng)求正常完成

    readyStateChange

    • 在 ajax 對(duì)象中有一個(gè)事件,叫做 readyStateChange 事件

    • 這個(gè)事件是專門用來監(jiān)聽 ajax 對(duì)象的 readyState 值改變的的行為

    • 也就是說只要 readyState 的值發(fā)生變化了,那么就會(huì)觸發(fā)該事件

    • 所以我們就在這個(gè)事件中來監(jiān)聽 ajax 的 readyState 是不是到 4 了

    const xhr = new XMLHttpRequest()xhr.open('get', './data.php')xhr.send()xhr.onreadyStateChange = function () {// 每次 readyState 改變的時(shí)候都會(huì)觸發(fā)該事件// 我們就在這里判斷 readyState 的值是不是到 4// 并且 http 的狀態(tài)碼是不是 200 ~ 299if (xhr.readyState === 4 && /^2\d{2|$/.test(xhr.status)) {// 這里表示驗(yàn)證通過// 我們就可以獲取服務(wù)端給我們響應(yīng)的內(nèi)容了}}

    responseText

    • ajax 對(duì)象中的 responseText 成員

    • 就是用來記錄服務(wù)端給我們的響應(yīng)體內(nèi)容的

    • 所以我們就用這個(gè)成員來獲取響應(yīng)體內(nèi)容就可以

    const xhr = new XMLHttpRequest()xhr.open('get', './data.php')xhr.send()xhr.onreadyStateChange = function () {if (xhr.readyState === 4 && /^2\d{2|$/.test(xhr.status)) {// 我們?cè)谶@里直接打印 xhr.responseText 來查看服務(wù)端給我們返回的內(nèi)容console.log(xhr.responseText)}}

    使用 ajax 發(fā)送請(qǐng)求時(shí)攜帶參數(shù)

    • 我們使用 ajax 發(fā)送請(qǐng)求也是可以攜帶參數(shù)的

    • 參數(shù)就是和后臺(tái)交互的時(shí)候給他的一些信息

    • 但是攜帶參數(shù) get 和 post 兩個(gè)方式還是有區(qū)別的

    發(fā)送一個(gè)帶有參數(shù)的 get 請(qǐng)求

    • get 請(qǐng)求的參數(shù)就直接在 url 后面進(jìn)行拼接就可以

    const xhr = new XMLHttpRequest()// 直接在地址后面加一個(gè) ?,然后以 key=value 的形式傳遞// 兩個(gè)數(shù)據(jù)之間以 & 分割xhr.open('get', './data.php?a=100&b=200')xhr.send()
      • 這樣服務(wù)端就能接受到兩個(gè)參數(shù)

      • 一個(gè)是 a,值是 100

      • 一個(gè)是 b,值是 200

    發(fā)送一個(gè)帶有參數(shù)的 post 請(qǐng)求

    • post 請(qǐng)求的參數(shù)是攜帶在請(qǐng)求體中的,所以不需要再 url 后面拼接

    const xhr = new XMLHttpRequest()xhr.open('post', './data.php')// 如果是用 ajax 對(duì)象發(fā)送 post 請(qǐng)求,必須要先設(shè)置一下請(qǐng)求頭中的 content-type// 告訴一下服務(wù)端我給你的是一個(gè)什么樣子的數(shù)據(jù)格式xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')// 請(qǐng)求體直接再 send 的時(shí)候?qū)懺?() 里面就行// 不需要問號(hào),直接就是 'key=value&key=value' 的形式xhr.send('a=100&b=200')
      • application/x-www-form-urlencoded 表示的數(shù)據(jù)格式就是 key=value&key=value

    同源策略

    • 同源策略是由瀏覽器給的

    • 瀏覽器不允許我們向別人發(fā)送請(qǐng)求,只能向自己的服務(wù)器發(fā)送請(qǐng)求

    • 當(dāng)我們想向別人的服務(wù)器發(fā)送請(qǐng)求的時(shí)候,就會(huì)被瀏覽器阻止了

    • 什么是 “別人的服務(wù)器” 呢?

      • 當(dāng) 請(qǐng)求協(xié)議/域名/端口號(hào) 有任意一個(gè)不同的時(shí)候,那么就算是別人的服務(wù)器

      • 這個(gè)時(shí)候就會(huì)觸發(fā)同源策略

    • 我們管觸發(fā)了 同源策略 的請(qǐng)求叫做跨域請(qǐng)求

    實(shí)現(xiàn)一個(gè)跨域請(qǐng)求

    • 有的時(shí)候我們是需要實(shí)現(xiàn)跨域請(qǐng)求的

    • 我們需要多個(gè)服務(wù)器給一個(gè)頁面提供數(shù)據(jù)

    • 那么這個(gè)時(shí)候我們就要想辦法解決跨域問題

    JSONP

    • jsonp 是我們實(shí)現(xiàn)跨域請(qǐng)求的手段,是把我們之前的東西組合在一起使用的技術(shù)手段而已

    • 利用的是 script 標(biāo)簽來實(shí)現(xiàn)

    script 標(biāo)簽的本質(zhì)

    • 瀏覽器給我們提供了一個(gè) script 標(biāo)簽

    • 它的本質(zhì)就是請(qǐng)求一個(gè)外部資源,是不受到同源策略的影響的

    • 同時(shí) script 標(biāo)簽的 src 屬性,也是一種請(qǐng)求,也能被服務(wù)器接收到

    • 并且:

      • script標(biāo)簽的src屬性請(qǐng)求回來的東西是一個(gè)字符串,瀏覽器會(huì)把這個(gè)字符串當(dāng)作 js 代碼來執(zhí)行

    • 所以我們就可以利用這個(gè) script 標(biāo)簽的 src 屬性來進(jìn)行跨域請(qǐng)求了

    配置代理(了解)

    • 代理,分成兩種,正向代理和反向代理

    正向代理

    • 有一個(gè)客戶端需要向一個(gè)非同源的服務(wù)器B發(fā)送請(qǐng)求

    • 我們搭建一個(gè)和客戶端同源的服務(wù)器A

    • 當(dāng)客戶端發(fā)送請(qǐng)求的時(shí)候,由服務(wù)器A來接受

    • 再由服務(wù)器A向服務(wù)器B發(fā)送請(qǐng)求,因?yàn)?同源策略是由瀏覽器給的,服務(wù)器之間沒有

    • 服務(wù)器B接受到請(qǐng)求以后,會(huì)處理請(qǐng)求,并把響應(yīng)返回給服務(wù)器A

    • 再由服務(wù)器A把響應(yīng)給到客戶端就可以了

    • 我們就可以用這個(gè)方式來進(jìn)行跨域請(qǐng)求了

    反向代理

    • 反向代理一般是用來做負(fù)載均衡的

    • 當(dāng)我請(qǐng)求一個(gè)服務(wù)器的時(shí)候,其實(shí)請(qǐng)求的是服務(wù)器端設(shè)置的代理服務(wù)器

    • 由代理服務(wù)器把若干大量的請(qǐng)求分發(fā)給不同的服務(wù)器進(jìn)行處理

    • 再由服務(wù)器把響應(yīng)給到代理服務(wù)器

    • 代理服務(wù)器返回給客戶端

    封裝 AJAX

    • ajax 使用起來太麻煩,因?yàn)槊看味家獙懞芏嗟拇a

    • 那么我們就封裝一個(gè) ajax 方法來讓我們使用起來簡單一些

    確定一下使用的方式

    • 因?yàn)橛幸恍﹥?nèi)容可以不傳遞,我們可以使用默認(rèn)值,所以選擇對(duì)象傳遞參數(shù)的方式// 使用的時(shí)候直接調(diào)用,傳遞一個(gè)對(duì)象就可以ajax({url: '', // 請(qǐng)求的地址type: '', // 請(qǐng)求方式async: '', // 是否異步data: '', // 攜帶的參數(shù)dataType: '', // 要不要執(zhí)行 json.parsesuccess: function () {} // 成功以后執(zhí)行的函數(shù)})

      • 確定好使用方式以后,就開始書寫封裝函數(shù)

    封裝

    function ajax(options) { // 先準(zhǔn)備一個(gè)默認(rèn)值 var defInfo = { url: '', // 地址不需要默認(rèn)值 type: 'GET', // 請(qǐng)求方式的默認(rèn)值是 GET async: false, // 默認(rèn)值是異步 data: '', // 參數(shù)沒有默認(rèn)值 dataType: 'string', // 默認(rèn)不需要執(zhí)行 json.parse success () {}, // 默認(rèn)是一個(gè)函數(shù)} // 先來判斷一下有沒有傳遞 url,如果沒有,直接拋出異常 if (!options.url) { throw new Error('url 必須傳遞')} // 有了 url 以后就,我們就把用戶傳遞的參數(shù)和我們的默認(rèn)數(shù)據(jù)合并 for (let key in options) { defInfo[key] = options[key]} // 接下來的一切我們都是使用我們的 defInfo 就可以了 // 第一步就是判斷參數(shù) data // data 可以不傳遞,可以為空 // data 也可以是一個(gè) key=value&key=value 格式的字符串 // data 也可以是一個(gè)對(duì)象 // 否則就拋出異常 if (!(typeof defInfo.data === 'string' && /^(\w+=\w+&?)*$/.test(defInfo.data) || Object.prototype.toString.call(defInfo.data) === '[object Object]')) { throw new Error('請(qǐng)按照要求傳遞參數(shù)')} // 參數(shù)處理完畢以后,在判斷 async 的數(shù)據(jù)類型 // 只能傳遞 布爾數(shù)據(jù)類型 if (typeof defInfo.async !== 'boolean') { throw new Error('async 參數(shù)只接受布爾數(shù)據(jù)類型')} // 在接下來就判斷 type // 請(qǐng)求方式我們只接受 GET 或著 POST if (!(defInfo.type.toUpperCase() === 'GET' || defInfo.type.toUpperCase() === 'POST')) { throw new Error('目前本插件只接受 GET 和 POST 方式,請(qǐng)期待更新')} // 接下來就是判斷 success 的判斷,必須是一個(gè)函數(shù) if (Object.prototype.toString.call(defInfo.success) !== '[object Function]') { throw new Error('success 只接受函數(shù)數(shù)據(jù)類型')} // 參數(shù)都沒有問題了 // 我們就要把 data 處理一下了 // 因?yàn)?data 有可能是對(duì)象,當(dāng) data 是一個(gè)對(duì)象的時(shí)候,我們要把它轉(zhuǎn)換成一個(gè)字符串 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} // 參數(shù)全部驗(yàn)證過了以后,我們就可以開始進(jìn)行正常的 ajax 請(qǐng)求了 // 1. 準(zhǔn)備一個(gè) ajax 對(duì)象 // 因?yàn)橐幚砑嫒輪栴},所以我們準(zhǔn)備一個(gè)函數(shù) function createXHR() { if (XMLHttpRequest) { return new XMLHttpRequest() } else { return new ActiveXObject('Microsoft.XMLHTTP') }} // 2. 創(chuàng)建一個(gè) ajax 對(duì)象 var xhr = createXHR() // 3. 進(jìn)行 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. 進(jìn)行 send xhr.send((defInfo.type.toUpperCase() === 'POST' ? `${defInfo.data}` : '')) // 5. 接受響應(yīng) xhr.onreadystatechange = function () { if (xhr.readyState === 4 && /2\d{2}/.test(xhr.status)) { // 表示成功,我們就要執(zhí)行 success // 但是要進(jìn)行 dataType 的判斷 if (defInfo.dataType === 'json') { defInfo.success(JSON.parse(xhr.responseText)) } else { defInfo.success() } }}}?苦逼的日子,有你真好看見這個(gè)分享了嗎,點(diǎn)它

    總結(jié)

    以上是生活随笔為你收集整理的ajax datatype_JavaScript学习笔记(二十七) ajax及ajax封装的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。