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

歡迎訪問 生活随笔!

生活随笔

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

javascript

网络编程-JavaScript中发送网络请求汇总

發(fā)布時(shí)間:2023/12/20 javascript 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网络编程-JavaScript中发送网络请求汇总 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 1.前后端分離優(yōu)勢(shì)
    • 2.HTTP協(xié)議的解析
      • 2.1 HTTP的介紹
      • 2.2 HTTP的組成
      • 2.3 HTTP的版本
      • 2.4 HTTP請(qǐng)求方式
      • 2.5 HTTP請(qǐng)求頭字段
      • 2.6 HTTP響應(yīng)狀態(tài)碼
      • 2.7 HTTP響應(yīng)頭
    • 3.AJAX網(wǎng)絡(luò)請(qǐng)求
      • 3.1 AJAX發(fā)送請(qǐng)求
      • 3.2 XHR的狀態(tài)
      • 3.3 XHR其他事件監(jiān)聽
      • 3.4 響應(yīng)數(shù)據(jù)和響應(yīng)類型
      • 3.5 HTTP的響應(yīng)狀態(tài)
      • 3.7 GET/POST傳遞參數(shù)
    • 4.AJAX網(wǎng)絡(luò)請(qǐng)求封裝
      • 補(bǔ)充: 過期時(shí)間和取消請(qǐng)求
        • 過期時(shí)間
        • 取消請(qǐng)求
    • 5.Fetch使用和上傳文件
      • 5.1 Fetch基本使用
      • 5.2 Fetch數(shù)據(jù)的響應(yīng)
      • 5.3 Fetch網(wǎng)絡(luò)請(qǐng)求的演練
      • 5.4 Fetch POST請(qǐng)求
      • 5.4 Fetch POST請(qǐng)求

1.前后端分離優(yōu)勢(shì)

早期的網(wǎng)頁都是通過后端渲染來完成的:服務(wù)器端渲染(SSR,server side render)

  • 客戶端發(fā)出請(qǐng)求 -> 服務(wù)端接收請(qǐng)求并返回相應(yīng)HTML文檔 -> 頁面刷新,客戶端加載新的HTML文檔;

服務(wù)器端渲染的缺點(diǎn):

  • 當(dāng)用戶點(diǎn)擊頁面中的某個(gè)按鈕向服務(wù)器發(fā)送請(qǐng)求時(shí),頁面本質(zhì)上只是一些數(shù)據(jù)發(fā)生了變化,而此時(shí)服務(wù)器卻要將重繪的整個(gè)頁面再返回給瀏覽器加載,這顯然有悖于程序員的“DRY( Don‘t repeat yourself )”原則;
  • 而且明明只是一些數(shù)據(jù)的變化卻迫使服務(wù)器要返回整個(gè)HTML文檔,這本身也會(huì)給網(wǎng)絡(luò)帶寬帶來不必要的開銷。

有沒有辦法在頁面數(shù)據(jù)變動(dòng)時(shí),只向服務(wù)器請(qǐng)求新的數(shù)據(jù),并且在阻止頁面刷新的情況下,動(dòng)態(tài)的替換頁面中展示的數(shù)據(jù)呢?

  • 答案正是“AJAX”。

AJAX是“Asynchronous JavaScript And XML”的縮寫(異步的JavaScript和XML),是一種實(shí)現(xiàn)無頁面刷新獲取服務(wù)器數(shù)據(jù)的技術(shù)。

  • AJAX最吸引人的就是它的“異步”特性,也就是說它可以在不重新刷新頁面的情況下與服務(wù)器通信,交換數(shù)據(jù),或更新頁面

你可以使用AJAX最主要的兩個(gè)特性做下列事 :

  • 不重新加載頁面的情況下發(fā)送請(qǐng)求給服務(wù)器
  • 接受并使用從服務(wù)器發(fā)來的數(shù)據(jù)。

這里有兩幅圖給大家理解一下:

  • 服務(wù)器端渲染
  • 前后端分離
  • 2.HTTP協(xié)議的解析

    2.1 HTTP的介紹

    什么是HTTP呢?我們來看一下維基百科的解釋

    • 超文本傳輸協(xié)議(英語:HyperText Transfer Protocol,縮寫:HTTP)是一種用于分布式、協(xié)作式和超媒體信息系統(tǒng)的應(yīng)用層協(xié)議
    • HTTP是萬維網(wǎng)的數(shù)據(jù)通信的基礎(chǔ),設(shè)計(jì)HTTP最初的目的是為了提供一種發(fā)布和接收HTML頁面的方法
    • 通過HTTP或者HTTPS協(xié)議請(qǐng)求的資源由統(tǒng)一資源標(biāo)識(shí)符(Uniform Resource Identifiers,URI)來標(biāo)識(shí)

    HTTP是一個(gè)客戶端(用戶)和服務(wù)端(網(wǎng)站)之間請(qǐng)求和響應(yīng)的標(biāo)準(zhǔn)。

    通過使用網(wǎng)頁瀏覽器、網(wǎng)絡(luò)爬蟲或者其它的工具,客戶端發(fā)起一個(gè)HTTP請(qǐng)求到服務(wù)器上指定端口(默認(rèn)端口為80);

    • 我們稱這個(gè)客戶端為用戶代理程序(user agent);

    響應(yīng)的服務(wù)器上存儲(chǔ)著一些資源,比如HTML文件和圖像。

    • 我們也稱這個(gè)響應(yīng)服務(wù)器為源服務(wù)器(origin server);

    我們網(wǎng)頁中的資源通常是被放在Web資源服務(wù)器中,由瀏覽器自動(dòng)發(fā)送HTTP請(qǐng)求來獲取、解析、展示的。

    目前我們頁面中很多數(shù)據(jù)是動(dòng)態(tài)展示的

    • 比如頁面中的數(shù)據(jù)展示、搜索數(shù)據(jù)、表單驗(yàn)證等等,也是通過在JavaScript中發(fā)送HTTP請(qǐng)求獲取的;

    2.2 HTTP的組成

    一次HTTP請(qǐng)求主要包括:請(qǐng)求(Request)和響應(yīng)(Response)(如下圖所示)

    請(qǐng)求又包含請(qǐng)求行請(qǐng)求頭、請(qǐng)求體 (如下圖所示)

    響應(yīng)也包含響應(yīng)行、響應(yīng)頭響應(yīng)體 (如下圖所示)

    2.3 HTTP的版本

    HTTP/0.9

    • 發(fā)布于1991年;
    • 只支持GET請(qǐng)求方法獲取文本數(shù)據(jù),當(dāng)時(shí)主要是為了獲取HTML頁面內(nèi)容;

    HTTP/1.0

    • 發(fā)布于1996年;
    • 支持POST、HEAD等請(qǐng)求方法,支持請(qǐng)求頭、響應(yīng)頭等,支持更多種數(shù)據(jù)類型(不再局限于文本數(shù)據(jù)) ;
    • 但是瀏覽器的每次請(qǐng)求都需要與服務(wù)器建立一個(gè)TCP連接,請(qǐng)求處理完成后立即斷開TCP連接,每次建立連接增加了性能損耗;

    HTTP/1.1(目前使用最廣泛的版本)

    • 發(fā)布于1997年;
    • 增加了PUT、DELETE等請(qǐng)求方法;
    • 采用持久連接(Connection: keep-alive),多個(gè)請(qǐng)求可以共用同一個(gè)TCP連接;

    HTTP/2.0, 2015年

    HTTP/3.0, 2018年

    2.4 HTTP請(qǐng)求方式

    在RFC中定義了一組請(qǐng)求方式,來表示要對(duì)給定資源執(zhí)行的操作

    • GET:GET 方法請(qǐng)求一個(gè)指定資源的表示形式,使用 GET 的請(qǐng)求應(yīng)該只被用于獲取數(shù)據(jù)。

    • HEAD:HEAD 方法請(qǐng)求一個(gè)與 GET 請(qǐng)求的響應(yīng)相同的響應(yīng),但沒有響應(yīng)體。

      比如在準(zhǔn)備下載一個(gè)文件前,先獲取文件的大小,再?zèng)Q定是否進(jìn)行下載;

    • POST:POST 方法用于將實(shí)體提交到指定的資源。

    • PUT:PUT 方法用請(qǐng)求有效載荷(payload)替換目標(biāo)資源的所有當(dāng)前表示;

    • DELETE:DELETE 方法刪除指定的資源;

    • PATCH:PATCH 方法用于對(duì)資源應(yīng)部分修改;

    • CONNECT:CONNECT 方法建立一個(gè)到目標(biāo)資源標(biāo)識(shí)的服務(wù)器的隧道,通常用在代理服務(wù)器,網(wǎng)頁開發(fā)很少用到。

    • TRACE:TRACE 方法沿著到目標(biāo)資源的路徑執(zhí)行一個(gè)消息環(huán)回測(cè)試。

    在開發(fā)中使用最多的是GET、POST請(qǐng)求

    • 在后續(xù)的后臺(tái)管理項(xiàng)目中,我們也會(huì)使用PATCH、DELETE請(qǐng)求

    2.5 HTTP請(qǐng)求頭字段

    在request對(duì)象的header中也包含很多有用的信息,客戶端會(huì)默認(rèn)傳遞過來一些信息(如下) :

    content-type: 這次請(qǐng)求攜帶的數(shù)據(jù)的類型

    • application/x-www-form-urlencoded:表示數(shù)據(jù)被編碼成以 ‘&’ 分隔的鍵 - 值對(duì),同時(shí)以 ‘=’ 分隔鍵和值
    • application/json:表示是一個(gè)json類型;
    • text/plain:表示是文本類型;
    • application/xml:表示是xml類型;
    • multipart/form-data:表示是上傳文件;

    content-length:文件的大小長(zhǎng)度

    keep-alive :

    • http是基于TCP協(xié)議的,但是通常在進(jìn)行一次請(qǐng)求和響應(yīng)結(jié)束后會(huì)立刻中斷;
    • 在http1.0中,如果想要繼續(xù)保持連接:
      • 瀏覽器需要在請(qǐng)求頭中添加 connection: keep-alive;
      • 服務(wù)器需要在響應(yīng)頭中添加 connection:keey-alive;
      • 當(dāng)客戶端再次放請(qǐng)求時(shí),就會(huì)使用同一個(gè)連接,直接一方中斷連接;
    • 在http1.1中,所有連接默認(rèn)是 connection: keep-alive的;
      • 不同的Web服務(wù)器會(huì)有不同的保持 keep-alive的時(shí)間;
      • Node中默認(rèn)是5s中;

    accept-encoding:告知服務(wù)器,客戶端支持的文件壓縮格式,比如js文件可以使用gzip編碼,對(duì)應(yīng) .gz文件;

    accept:告知服務(wù)器,客戶端可接受文件的格式類型;

    user-agent:客戶端相關(guān)的信息;

    2.6 HTTP響應(yīng)狀態(tài)碼

    Http狀態(tài)碼(Http Status Code)是用來表示Http響應(yīng)狀態(tài)的數(shù)字代碼

    • Http狀態(tài)碼非常多,可以根據(jù)不同的情況,給客戶端返回不同的狀態(tài)碼;
    常見HTTP狀態(tài)碼狀態(tài)描述信息說明
    200OK客戶端請(qǐng)求成功
    201CreatedPOST請(qǐng)求,創(chuàng)建新的資源
    301Moved Permanently請(qǐng)求資源的URL已經(jīng)修改,響應(yīng)中會(huì)給出新的URL
    400Bad Request客戶端的錯(cuò)誤,服務(wù)器無法或者不進(jìn)行處理
    401Unauthorized未授權(quán)的錯(cuò)誤,必須攜帶請(qǐng)求的身份信息
    403Forbidden客戶端沒有權(quán)限訪問,被拒接
    404Not Found服務(wù)器找不到請(qǐng)求的資源。
    500Internal Server Error服務(wù)器遇到了不知道如何處理的情況。
    503Service Unavailable服務(wù)器不可用,可能處理維護(hù)或者重載狀態(tài),暫時(shí)無法訪問

    更多響應(yīng)碼介紹在MDN文檔上, 鏈接給到大家: MDN上響應(yīng)碼文檔: https://developer.mozilla.org/zh-CN/docs/web/http/status

    2.7 HTTP響應(yīng)頭

    響應(yīng)的header中包括一些服務(wù)器給客戶端的信息

    [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-L3n6aQgp-1657070357626)(img/Snipaste_2022-07-05_11-06-57.png)]

    3.AJAX網(wǎng)絡(luò)請(qǐng)求

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

    AJAX 是異步的 JavaScript 和 XML(Asynchronous JavaScript And XML)

    • 它可以使用 JSON,XML,HTML 和 text 文本等格式發(fā)送和接收數(shù)據(jù);

    如何來完成AJAX請(qǐng)求呢?

    • 第一步:創(chuàng)建網(wǎng)絡(luò)請(qǐng)求的AJAX對(duì)象(使用XMLHttpRequest)

    • 第二步:監(jiān)聽XMLHttpRequest對(duì)象狀態(tài)的變化,或者監(jiān)聽onload事件(請(qǐng)求完成時(shí)觸發(fā));

    • 第三步:配置網(wǎng)絡(luò)請(qǐng)求(通過open方法), open方法可以傳入兩個(gè)參數(shù);

      參數(shù)一: method(請(qǐng)求的方式: get, post …)

      參數(shù)二: url(請(qǐng)求的地址)

    • 第四步:發(fā)送send網(wǎng)絡(luò)請(qǐng)求;

    【演示代碼】

    // 1.創(chuàng)建網(wǎng)絡(luò)請(qǐng)求對(duì)象 const xhr = new XMLHttpRequest()// 2.監(jiān)聽對(duì)象狀態(tài)的變化 xhr.addEventListener("readystatechange", function() {// 拿到網(wǎng)絡(luò)請(qǐng)求的結(jié)果console.log(xhr.response) })// 3.配置網(wǎng)絡(luò)請(qǐng)求 // 參數(shù)一: 請(qǐng)求的方式; 參數(shù)二: 要請(qǐng)求的url地址 xhr.open("get", "http://192.168.0.110:1888")// 4.發(fā)生網(wǎng)絡(luò)請(qǐng)求 xhr.send()

    發(fā)送同步請(qǐng)求:

    • 我們發(fā)送網(wǎng)絡(luò)請(qǐng)求, 默認(rèn)是異步的, 但是我們也可以發(fā)送同步的網(wǎng)絡(luò)請(qǐng)求

    • 我們是需要將open的第三個(gè)參數(shù)設(shè)置為false (默認(rèn)時(shí)true), 就可以開啟同步的請(qǐng)求

    • 當(dāng)然我們實(shí)際開發(fā)還是用異步的請(qǐng)求

    // 開啟同步 xhr.open("get", "http://192.168.0.110:1888", false)

    3.2 XHR的狀態(tài)

    事實(shí)上,我們?cè)谝淮尉W(wǎng)絡(luò)請(qǐng)求中看到狀態(tài)發(fā)生了很多次變化,這是因?yàn)閷?duì)于一次請(qǐng)求來說包括如下的狀態(tài):

    值狀態(tài)描述
    0UNSENT代理被創(chuàng)建,但尚未調(diào)用 open() 方法。
    1OPENEDopen() 方法已經(jīng)被調(diào)用。
    2HEADERS_RECEIVEDsend() 方法已經(jīng)被調(diào)用,并且頭部和狀態(tài)已經(jīng)可獲得。
    3LOADING下載中;responseText 屬性已經(jīng)包含部分?jǐn)?shù)據(jù)。
    4DONE下載操作已完成。

    狀態(tài)0我們是監(jiān)聽不到的


    例如: 我們想要獲取結(jié)果, 應(yīng)該在下載操作已完成后獲取

    // 1.創(chuàng)建網(wǎng)絡(luò)請(qǐng)求對(duì)象 const xhr = new XMLHttpRequest()// 2.監(jiān)聽對(duì)象狀態(tài)的變化 xhr.addEventListener("readystatechange", function() {// 狀態(tài)不為4的話直接returnif (xhr.readyState !== XMLHttpRequest.DONE) return// 拿到的結(jié)果是一個(gè)字符串, 我們可以轉(zhuǎn)成js對(duì)象const resJSON = JSON.parse(xhr.response)console.log(resJSON) })// 3.配置網(wǎng)絡(luò)請(qǐng)求 // 參數(shù)一: 請(qǐng)求的方式; 參數(shù)二: 要請(qǐng)求的url地址 xhr.open("get", "http://192.168.0.110:1888")// 4.發(fā)生網(wǎng)絡(luò)請(qǐng)求 xhr.send()

    注意<:這個(gè)狀態(tài)并非是HTTP的響應(yīng)狀態(tài),而是記錄的XMLHttpRequest對(duì)象的狀態(tài)變化。

    • http響應(yīng)狀態(tài)通過status獲取;

    3.3 XHR其他事件監(jiān)聽

    我們除了可以監(jiān)聽readystatechange之外, 還有其他的事件可以監(jiān)聽

    • loadstart:請(qǐng)求開始。
    • progress: 一個(gè)響應(yīng)數(shù)據(jù)包到達(dá),此時(shí)整個(gè) response body 都在 response 中。
    • abort:調(diào)用 xhr.abort() 取消了請(qǐng)求。
    • error:發(fā)生連接錯(cuò)誤,例如,域錯(cuò)誤。不會(huì)發(fā)生諸如 404 這類的 HTTP 錯(cuò)誤。
    • load:請(qǐng)求成功完成。
    • timeout:由于請(qǐng)求超時(shí)而取消了該請(qǐng)求(僅發(fā)生在設(shè)置了 timeout 的情況下)。
    • loadend:在 load,error,timeout 或 abort 之后觸發(fā)。

    我們也可以在load中獲取請(qǐng)求數(shù)據(jù):

    // 在load中獲取請(qǐng)求結(jié)果 xhr.addEventListener("load", function() {console.log(xhr.response) })

    3.4 響應(yīng)數(shù)據(jù)和響應(yīng)類型

    發(fā)送了請(qǐng)求后,我們需要獲取對(duì)應(yīng)的結(jié)果:response屬性

    • XMLHttpRequest response 屬性返回響應(yīng)的正文內(nèi)容
    • 返回的類型取決于responseType的屬性設(shè)置

    通過responseType可以設(shè)置獲取數(shù)據(jù)的類型

    • 如果將 responseType 的值設(shè)置為空字符串,則會(huì)使用 text 作為默認(rèn)值。
    • 設(shè)置數(shù)據(jù)類型, 一般在監(jiān)聽事件之后, 且在send方法之前
    const xhr = new XMLHttpRequest()xhr.addEventListener("load", function() {console.log(xhr.response) })// 由于responseType默認(rèn)值為test, 因此我們拿到的結(jié)果是一個(gè)字符串 // 告知xhr獲取的數(shù)據(jù)為json類型 xhr.responseType = "json"// json類型接口 xhr.open("get", "http://123.207.32.32:8000/home/multidata")xhr.send()

    和responseText、responseXML的區(qū)別

    • 早期通常服務(wù)器返回的數(shù)據(jù)是普通的文本和XML,所以我們通常會(huì)通過responseText、 responseXML來獲取響應(yīng)結(jié)果 , 之后將它們轉(zhuǎn)化成JavaScript對(duì)象形式;
    • 目前服務(wù)器基本返回的都是json數(shù)據(jù),直接設(shè)置為json即可

    3.5 HTTP的響應(yīng)狀態(tài)

    前面我們提到, XMLHttpRequest的state是用于記錄xhr對(duì)象本身的狀態(tài)變化,并非針對(duì)于HTTP的網(wǎng)絡(luò)請(qǐng)求狀態(tài)。

    如果我們希望獲取HTTP響應(yīng)的網(wǎng)絡(luò)狀態(tài),可以通過status和statusText來獲取

    • status是獲取狀態(tài)碼
    • statusText是獲取狀態(tài)描述
    const xhr = new XMLHttpRequest()xhr.addEventListener("load", function() {console.log(xhr.response)// 1.獲取狀態(tài)碼console.log(xhr.status) // 200// 2.獲取狀態(tài)描述console.log(xhr.statusText) // OK })xhr.responseType = "json"xhr.open("get", "http://123.207.32.32:8000/home/multidata")xhr.send()

    我們寫一個(gè)不存在的接口, 測(cè)試一下狀態(tài)碼和狀態(tài)描述

    const xhr = new XMLHttpRequest()xhr.addEventListener("load", function() {console.log(xhr.response) // null// 1.獲取狀態(tài)碼console.log(xhr.status) // 404// 2.獲取狀態(tài)描述console.log(xhr.statusText) // Not Found })xhr.responseType = "json"xhr.open("get", "http://123.207.32.32:8000/aaa/bbb/ccc")xhr.send()

    大家可以再看看剛剛的常用狀態(tài)碼表格

    常見HTTP狀態(tài)碼狀態(tài)描述信息說明
    200OK客戶端請(qǐng)求成功
    201CreatedPOST請(qǐng)求,創(chuàng)建新的資源
    301Moved Permanently請(qǐng)求資源的URL已經(jīng)修改,響應(yīng)中會(huì)給出新的URL
    400Bad Request客戶端的錯(cuò)誤,服務(wù)器無法或者不進(jìn)行處理
    401Unauthorized未授權(quán)的錯(cuò)誤,必須攜帶請(qǐng)求的身份信息
    403Forbidden客戶端沒有權(quán)限訪問,被拒接
    404Not Found服務(wù)器找不到請(qǐng)求的資源。
    500Internal Server Error服務(wù)器遇到了不知道如何處理的情況。
    503Service Unavailable服務(wù)器不可用,可能處理維護(hù)或者重載狀態(tài),暫時(shí)無法訪問

    3.7 GET/POST傳遞參數(shù)

    在開發(fā)中,我們使用最多的是GET和POST請(qǐng)求,在發(fā)送請(qǐng)求的過程中,我們也可以傳遞給服務(wù)器數(shù)據(jù)。

    常見的傳遞給服務(wù)器數(shù)據(jù)的方式有如下幾種 :

    • 方式一:GET請(qǐng)求的query參數(shù)(常用)

      const xhr = new XMLHttpRequest()xhr.addEventListener("load", function() {// 傳入的參數(shù)服務(wù)器會(huì)返回console.log(xhr.response) })xhr.responseType = "json"// 在傳入的url輸入查詢字符串傳遞參數(shù) xhr.open("get", "http://123.207.32.32:1888/02_param/get?name=kaisa&age=18&address=成都市" )xhr.send()

      請(qǐng)求結(jié)果

    • 方式二:POST請(qǐng)求 x-www-form-urlencoded 格式

      const xhr = new XMLHttpRequest()xhr.addEventListener("load", function() {console.log(xhr.response) })xhr.responseType = "json"// 1.發(fā)送post請(qǐng)求 xhr.open("post", "http://123.207.32.32:1888/02_param/posturl")// 2.告知服務(wù)器要發(fā)送數(shù)據(jù)的格式 xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded") // 3.在請(qǐng)求體中傳入?yún)?shù) xhr.send("name=kaisa&age=18&address=成都市")

      請(qǐng)求結(jié)果

    • 方式三:POST請(qǐng)求 FormData 格式

    • 方式四:POST請(qǐng)求 JSON 格式(常用)

      const xhr = new XMLHttpRequest()xhr.addEventListener("load", function() {console.log(xhr.response) })xhr.responseType = "json"// 1.發(fā)送post請(qǐng)求 xhr.open("post", "http://123.207.32.32:1888/02_param/posturl")// 2.告知服務(wù)器要發(fā)送數(shù)據(jù)的格式 xhr.setRequestHeader("Content-type", "application/json")// 3.發(fā)送JSON格式的字符串 xhr.send(JSON.stringify({ name: "kaisa", age: 18, height: 1.88 }))

      請(qǐng)求結(jié)果

    4.AJAX網(wǎng)絡(luò)請(qǐng)求封裝

    在實(shí)際開發(fā)中, 我們并不會(huì)自己封裝AJAX, 而是直接使用axios庫, 再對(duì)axios庫進(jìn)行二次封裝

    我們封裝AJAX原因是借此練習(xí)一下前面所學(xué)的知識(shí)

    由于我們每次使用網(wǎng)絡(luò)請(qǐng)求, 都寫寫很多行同樣的代碼, 使用起來是非常不方便的, 我們封裝的目的就是為了使用起來更方便

    封裝步驟的解釋寫在代碼注釋里面, 源代碼和測(cè)試代碼給大家

    // 定義一個(gè)函數(shù)封裝ajax, // 由于使用參數(shù)可能會(huì)傳很多個(gè), 因此我們可以讓使用者傳入一個(gè)對(duì)象 function myajax({url,method = "get",date = {},success,failure } = {}) {// 1.創(chuàng)建對(duì)象const xhr = new XMLHttpRequest()// 2.監(jiān)聽數(shù)據(jù)xhr.onload = function() {// 用響應(yīng)碼判斷是否成功if (xhr.status >= 200 && xhr.status < 300) {success && success(xhr.response)} else {failure && failure({ status: xhr.status, message: xhr.statusText })}}// 3.設(shè)置響應(yīng)類型xhr.responseType = "json"// 考慮get請(qǐng)求放在date對(duì)象中的情況單獨(dú)處理if (method.toUpperCase() === "GET") {const urlStrings = []for (key in date) {urlStrings.push(`${key}=${date[key]}`)}url = url + "?" + urlStrings.join("&")xhr.open(method, url)xhr.send()} else {// 4.open方法xhr.open(method, url)// 5.send方法xhr.setRequestHeader("Content-type", "application/json")xhr.send(JSON.stringify(date))} }// 測(cè)試get請(qǐng)求 myajax({url: "http://123.207.32.32:1888/02_param/get",date: {name: "get",age: 18},// 傳入一個(gè)請(qǐng)求成功的回調(diào)success: function(res) {console.log(res)},// 傳入失敗的回調(diào)failure: function(err) {console.log("err", err)} })// 測(cè)試post請(qǐng)求 myajax({url: "http://123.207.32.32:1888/02_param/posturl",method: "post",// 傳入一個(gè)請(qǐng)求成功的回調(diào)success: function(res) {console.log(res)},date: {name: "post",age: 18},// 傳入失敗的回調(diào)failure: function(err) {console.log("err", err)} })

    我們對(duì)上面的基本封裝做一點(diǎn)優(yōu)化, 為了防止回調(diào)地獄的情況出現(xiàn), 我們可以返回一個(gè)promise, 并且不需要再傳入成功的回調(diào)和失敗的回調(diào), 因?yàn)閜romise中有

    function myajax({url,method = "get",date = {} } = {}) {// 返回一個(gè)promisereturn new Promise((resolve, reject) => {const xhr = new XMLHttpRequest() xhr.onload = function() {if (xhr.status >= 200 && xhr.status < 300) {// 使用resolve成功的回調(diào)resolve(xhr.response)} else {// 使用reject失敗的回調(diào)reject({ status: xhr.status, message: xhr.statusText })}} xhr.responseType = "json" if (method.toUpperCase() === "GET") {const urlStrings = []for (key in date) {urlStrings.push(`${key}=${date[key]}`)}url = url + "?" + urlStrings.join("&") xhr.open(method, url)xhr.send()} else {xhr.open(method, url) xhr.setRequestHeader("Content-type", "application/json")xhr.send(JSON.stringify(date))}}) }// 測(cè)試get請(qǐng)求 myajax({url: "http://123.207.32.32:1888/02_param/get",date: {name: "get",age: 18} // then中成功的結(jié)果 }).then(res => {console.log(res) // catch中失敗的結(jié)果 }).catch(err => {console.log(err) })// 測(cè)試post請(qǐng)求 myajax({url: "http://123.207.32.32:1888/02_param/posturl",method: "post",date: {name: "post",age: 18} // then中成功的結(jié)果 }).then(res => {console.log(res) // catch中失敗的結(jié)果 }).catch(err => {console.log(err) })

    補(bǔ)充: 過期時(shí)間和取消請(qǐng)求

    下面我用的是一個(gè)延時(shí)的接口

    過期時(shí)間

    在網(wǎng)絡(luò)請(qǐng)求的過程中,為了避免過長(zhǎng)的時(shí)間服務(wù)器無法返回?cái)?shù)據(jù),通常我們會(huì)為請(qǐng)求設(shè)置一個(gè)超時(shí)時(shí)間:timeout。

    • 當(dāng)達(dá)到超時(shí)時(shí)間后依然沒有獲取到數(shù)據(jù),那么這個(gè)請(qǐng)求會(huì)自動(dòng)被取消掉
    • 默認(rèn)值為0,表示沒有設(shè)置超時(shí)時(shí)間;

    下面寫個(gè)案例, 如果超過3000毫秒沒有請(qǐng)求到數(shù)據(jù)就取消本次網(wǎng)絡(luò)請(qǐng)求

    • 請(qǐng)求超時(shí)可以在timeout中監(jiān)聽
    const xhr = new XMLHttpRequest()xhr.addEventListener("load", function() {console.log(xhr.response) })// 請(qǐng)求超時(shí)可以在timeout中監(jiān)聽 xhr.addEventListener("timeout", function() {console.log("請(qǐng)求超時(shí)") })xhr.responseType = "json"xhr.timeout = 3000xhr.open("get", "http://123.207.32.32:1888/01_basic/timeout")xhr.send()

    取消請(qǐng)求

    取消網(wǎng)絡(luò)請(qǐng)求, 我們也可以通過abort方法強(qiáng)制 (手動(dòng)) 取消請(qǐng)求

    • 請(qǐng)求取消可以在abort中監(jiān)聽
    <button>取消請(qǐng)求</button><script>const xhr = new XMLHttpRequest() xhr.addEventListener("load", function() {console.log(xhr.response)}) // 請(qǐng)求取消可以在abort中監(jiān)聽xhr.addEventListener("abort", function() {console.log("請(qǐng)求已取消")}) xhr.responseType = "json" xhr.timeout = 3000 xhr.open("get", "http://123.207.32.32:1888/01_basic/timeout") xhr.send() // 監(jiān)聽按鈕點(diǎn)擊取消請(qǐng)求const btnEl = document.querySelector("button")btnEl.onclick = function() {xhr.abort()} </script>

    5.Fetch使用和上傳文件

    5.1 Fetch基本使用

    Fetch可以看做是早期的XMLHttpRequest的替代方案,它提供了一種更加現(xiàn)代的處理方案:

    比如返回值是一個(gè)Promise,提供了一種更加優(yōu)雅的處理結(jié)果方式

    • 在請(qǐng)求發(fā)送成功時(shí),調(diào)用resolve回調(diào)then;
    • 在請(qǐng)求發(fā)送失敗時(shí),調(diào)用reject回調(diào)catch;

    比如不像XMLHttpRequest一樣,所有的操作都在一個(gè)對(duì)象上

    fetch函數(shù)的使用

    fetch(input[, init])

    input:定義要獲取的資源地址,可以是一個(gè)URL字符串,也可以使用一個(gè)Request對(duì)象(實(shí)驗(yàn)性特性)類型;

    init:其他初始化參數(shù), 是一個(gè)對(duì)象

    • method: 請(qǐng)求使用的方法,如 GET、POST;
    • headers: 請(qǐng)求的頭信息;
    • body: 請(qǐng)求的 body 信息;

    【演示代碼】

    發(fā)送一個(gè)get請(qǐng)求(先了解一下 馬上會(huì)詳細(xì)分析)

    fetch("http://123.207.32.32:8000/home/multidata").then(res => {// 獲取具體的結(jié)果還需調(diào)用一次// 如果是文本就res.text, 其他的同樣的道理res.json().then(res => {console.log(res)}) }).catch(err => {console.log(err) })

    5.2 Fetch數(shù)據(jù)的響應(yīng)

    Fetch的數(shù)據(jù)響應(yīng)主要分為兩個(gè)階段 :

    階段一:當(dāng)服務(wù)器返回了響應(yīng)(response)

    • fetch 返回的 promise 就使用內(nèi)建的 Response class 對(duì)象來對(duì)響應(yīng)頭進(jìn)行解析;
    • 在這個(gè)階段,我們可以通過檢查響應(yīng)頭,來檢查 HTTP 狀態(tài)以確定請(qǐng)求是否成功;
    • 如果 fetch 無法建立一個(gè) HTTP 請(qǐng)求,例如網(wǎng)絡(luò)問題,亦或是請(qǐng)求的網(wǎng)址不存在,那么 promise 就會(huì) reject;
    • 異常的 HTTP 狀態(tài),例如 404 或 500,不會(huì)導(dǎo)致出現(xiàn) error;

    我們可以在 response 的屬性中看到 HTTP 狀態(tài)

    • status:HTTP 狀態(tài)碼,例如 200;
    • ok:布爾值,如果 HTTP 狀態(tài)碼為 200-299,則為 true;
    fetch("http://123.207.32.32:8000/home/multidata").then(res => {// response中查看狀態(tài)碼, 狀態(tài)描述console.log(res.status) // 200console.log(res.statusText) // OKconsole.log(res.ok) // true}).catch(err => {console.log(err) })

    第二階段,為了獲取 response body,我們需要使用一個(gè)其他的方法調(diào)用, 這個(gè)方法同樣返回Promise。

    • response.text() —— 讀取 response,并以文本形式返回 response
    • response.json() —— 將 response 解析為 JSON
    fetch("http://123.207.32.32:8000/home/multidata").then(res => {// 第二階段, 同樣返回Promiseres.json().then(res => {// 拿到最終結(jié)果console.log(res)})}).catch(err => {console.log(err) })

    5.3 Fetch網(wǎng)絡(luò)請(qǐng)求的演練

    基于Promise的使用方案

    fetch("http://123.207.32.32:8000/home/multidata").then(res => {// 獲取具體的結(jié)果還需調(diào)用一次// 如果是文本就res.text, 其他的同樣的道理return res.json() }).then(res => {console.log(res) }).catch(err => {console.log(err) })

    基于async、await的使用方案

    async function getDate() {const response1 = await fetch("http://123.207.32.32:8000/home/multidata")const response2 = await response1.json()// 打印結(jié)果console.log(response2) }getDate()

    5.4 Fetch POST請(qǐng)求

    創(chuàng)建一個(gè) POST 請(qǐng)求,或者其他方法的請(qǐng)求,我們需要使用 fetch 選項(xiàng)

    method:HTTP 方法,例如 POST,

    body:request body,其中之一:

    • 字符串(例如 JSON 編碼的),
    • FormData 對(duì)象,以 multipart/form-data 形式發(fā)送數(shù)據(jù),
    async function getDate() {// post請(qǐng)求需要在fetch方法中傳入第二個(gè)參數(shù)const response1 = await fetch("http://123.207.32.32:1888/02_param/postjson",{method: "post",headers: {"Content-type": "application/json"},// 參數(shù)防砸body中body: JSON.stringify({username: "aaa",postname: "123456"})})const response2 = await response1.json()// 打印結(jié)果console.log(response2) }getDate() fetch("http://123.207.32.32:8000/home/multidata")const response2 = await response1.json()// 打印結(jié)果console.log(response2) }getDate()

    5.4 Fetch POST請(qǐng)求

    創(chuàng)建一個(gè) POST 請(qǐng)求,或者其他方法的請(qǐng)求,我們需要使用 fetch 選項(xiàng)

    method:HTTP 方法,例如 POST,

    body:request body,其中之一:

    • 字符串(例如 JSON 編碼的),
    • FormData 對(duì)象,以 multipart/form-data 形式發(fā)送數(shù)據(jù),
    async function getDate() {// post請(qǐng)求需要在fetch方法中傳入第二個(gè)參數(shù)const response1 = await fetch("http://123.207.32.32:1888/02_param/postjson",{method: "post",headers: {"Content-type": "application/json"},// 參數(shù)防砸body中body: JSON.stringify({username: "aaa",postname: "123456"})})const response2 = await response1.json()// 打印結(jié)果console.log(response2) }getDate()

    總結(jié)

    以上是生活随笔為你收集整理的网络编程-JavaScript中发送网络请求汇总的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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