天天看點

AJAX(一):初識AJAX、http協定、配置環境、發送AJAX請求、請求時的問題一、什麼是AJAX?二、HTTP協定三、AJAX案例準備工作四、發送AJAX請求五、AJAX請求的幾個問題

AJAX學習筆記

  • 一、什麼是AJAX?
    • 1.原生AJAX
    • 2.XML
    • 3.AJAX的優缺點
  • 二、HTTP協定
    • 1.請求封包
    • 2.響應封包
  • 三、AJAX案例準備工作
    • 1.安裝express
    • 2.建立一個服務端
    • 3.nodemon實作儲存自動重新開機服務
  • 四、發送AJAX請求
    • 1.發送GET請求
    • 2.發送POST請求
    • 3.JSON響應
      • (1)手動把JSON字元串轉換為js對象
      • (2)自動把JSON字元串轉換為js對象
  • 五、AJAX請求的幾個問題
    • 1.IE緩存問題
    • 2.AJAX請求逾時與網絡異常處理
    • 3.AJAX手動取消請求
    • 4.AJAX請求重複發送問題

一、什麼是AJAX?

1.原生AJAX

AJAX 全稱為Asynchronous Javascript And XML。就是異步的JS和XML。通過AJAX 可以在浏覽器中向伺服器發送異步請求,最大的優勢:無重新整理擷取資料。AJAX 不是新的程式設計語言,而是一種将現有的标準組合在一起使用的新方式。

2.XML

可擴充标記語言。XML被設計用來傳輸和存儲資料。XML和HTML類似,不同的是HTML中都是預定義标簽,而XML中沒有預定義标簽,全部都是自定義标簽,用來表示一些資料。(目前已經被JSON取代)

3.AJAX的優缺點

優點:

(1)可以無需重新整理頁面而與伺服器端進行通信。

(2)允許你根據使用者事件來更新部分頁面内容。

缺點:

(1)沒有浏覽曆史,不能回退。

(2)存在跨域問題(同源)

(3)SEO不友好(檢視源代碼中無法查找到)

二、HTTP協定

HTTP全稱為hypertext transport protocol 協定【超文本傳輸協定】,協定詳細規定了浏覽器和網際網路伺服器之間互相通信的規則。

重點格式與參數:

1.請求封包

行:

POST

/URL HTTP

協定版本

頭:

Host:值

Cookie: 值

Content-type:值

User-Agent:值

等等

空行:

體:如果是GET請求體為空,如果是POST可以不為空

2.響應封包

行:

HTTP協定版本

響應狀态碼

響應狀态字元串

頭:

Content-type:值

Content-length:值

Content-encoding:值

等等

空行:

體:HTML文法内容

三、AJAX案例準備工作

1.安裝express

之前腳手架的時候配置過node環境,是以這裡的安裝非常順利,沒有任何報錯。隻需要在vscode => 終端 => 目前目錄中 => 輸入

npm i express

就歐了。如果出錯了去翻我的配置Vue腳手架筆記。

其實這裡也可以安裝到全局,也就是安到node.js的根目錄裡,好像是

npm i express -g

2.建立一個服務端

在目前目錄建立個js檔案(不一定非要在express安裝的根目錄噢),然後在終端 => 目前目錄下 => 輸入

node 檔案名

就可以啟動服務

AJAX(一):初識AJAX、http協定、配置環境、發送AJAX請求、請求時的問題一、什麼是AJAX?二、HTTP協定三、AJAX案例準備工作四、發送AJAX請求五、AJAX請求的幾個問題
//1.引入express
const express = require('express');

//2.建立應用對象
const app = express();

//3.建立路由規則
//request是對請求封包的封裝
//response是對響應封包的封裝
app.get('/', (request, response) => {
    //設定響應
    response.send('HELLO EXPRESS');
})

//4.監聽端口啟動服務
app.listen(8000, () => {
    console.log('服務已經啟動,8000端口監聽中...');
})
           

網頁打開:

AJAX(一):初識AJAX、http協定、配置環境、發送AJAX請求、請求時的問題一、什麼是AJAX?二、HTTP協定三、AJAX案例準備工作四、發送AJAX請求五、AJAX請求的幾個問題

端口釋放:Ctrl+c

3.nodemon實作儲存自動重新開機服務

終端運作

npm install -g nodemon

安裝nodemon,這樣每次儲存就會自動重新開機服務,比較友善(副作用是所有html都無法儲存時自動調整格式),使用時還是在目前目錄

nodemon+檔案名

,如

nodemon server.js

(之前是

node server.js

四、發送AJAX請求

1.發送GET請求

點選按鈕div中呈現響應體:點選按鈕發送AJAX請求給伺服器,然後把響應體拿過來放到div中。

沒見過這些東西,照着敲的,仔細看我寫的注釋

<button>點選發送請求</button>
<div id="result"></div>
           
//擷取button元素
const btn = document.querySelector('button');
const result = document.querySelector('#result');
btn.addEventListener('click', function() {
    //1.建立對象
    const xhr = new XMLHttpRequest();
    //2.初始化,設定請求的方法和url
    xhr.open('GET','http://127.0.0.1:8000/server?a=1&b=2&c=3');
    //3.發送
    xhr.send();

    //4.事件綁定,處理服務端傳回的結果
    //on 當……的時候
    //readyState是xhr對象中的屬性,表示狀态0 1 2 3 4 
    //其中0-未初始化 1-open調用完畢 2-send調用完畢 3-服務端傳回了部分結果 4-服務端傳回了所有結果
    //change 改變
    xhr.onreadystatechange = function () {
        //判斷服務端是否傳回了所有結果
        if(xhr.readyState === 4) {
            //判斷響應狀态碼 200 404 403 401 500
            // 2xx ,2開頭都表示成功
            if(xhr.status >= 200 && xhr.status < 300){
                //如果響應成功處理結果 行 頭 空行 體
                console.log('狀态碼:',xhr.status); //狀态碼
                console.log('狀态字元串:',xhr.statusText); //狀态字元串
                console.log('響應頭:',xhr.getAllResponseHeaders()); //所有的響應頭
                console.log('響應體:',xhr.response); //響應體

                //設定result文本
                result.innerHTML = xhr.response;
            }
        }
    }
})
           

設定url參數:

用?隔開,=指派,&分隔

例如:

http://127.0.0.1:8000/server?a=1&b=2&c=3

看不懂的服務端server.js檔案:

//1.引入express
const express = require('express');

//2.建立應用對象
const app = express();

//3.建立路由規則
//request是對請求封包的封裝
//response是對響應封包的封裝
app.get('/server', (request, response) => {
    //設定響應頭
    response.setHeader('Access-Control-Allow-Origin', '*');

    //設定響應體
    response.send('HELLO AJAX');
})

//4.監聽端口啟動服務
app.listen(8000, () => {
    console.log('服務已經啟動,8000端口監聽中...');
})
           

2.發送POST請求

滑鼠經過div發送AJAX請求,然後拿回來響應體放在div中

仔細對比GET和POST的不同,好像這個傳參在send中寫,類型随便??

還有就是可以

xhr.setRequestHeader

設定請求頭,仔細看看注釋

const result = document.querySelector('#result');
result.addEventListener('mouseover' ,function() {
   //1.建立對象
   const xhr = new XMLHttpRequest();
   //2.初始化 設定類型與url
   xhr.open('POST','http://127.0.0.1:8000/server');
   //設定請求頭:固定寫法,第一個參數設定請求體内容類型,第二個參數是參數查詢字元串的類型
   xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); 
   //3.發送請求,在這裡傳參,任意類型都歐
   xhr.send('a=1&b=2&c=3');
   // xhr.send('a:1&b:2&c:3'); 
   // xhr.send('1232142412421312');
   //4.綁定事件
   xhr.onreadystatechange = function() {
       //判斷服務端是否傳回所有結果
       if(xhr.readyState === 4) {
           //判斷響應是否成功
           if(xhr.status >=200 && xhr.status<300) {
               //處理服務端傳回的結果
               result.innerHTML = xhr.response;
           }
       }
   }
})
           

server.js

//1.引入express
const express = require('express');

//2.建立應用對象
const app = express();

//3.建立路由規則
//request是對請求封包的封裝
//response是對響應封包的封裝
//POST請求
app.post('/server', (request, response) => {
    //設定響應頭
    response.setHeader('Access-Control-Allow-Origin', '*');
    //設定響應體
    response.send('HELLO AJAX POST');
})

//4.監聽端口啟動服務
app.listen(8000, () => {
    console.log('服務已經啟動,8000端口監聽中...');
})
           

3.JSON響應

服務端響應體也可以設定為一個資料發送過去,但是不能直接寫,要通過

JSON.stringify(資料)

把資料轉換為JSON字元串

app.get('/json-server', (request, response) => {
    //設定響應頭
    response.setHeader('Access-Control-Allow-Origin', '*');
    //響應一個資料
    const data = { name: 'ht' };
    let str = JSON.stringify(data); //對對象進行字元串轉換
    //設定響應體
    response.send(str);
})
           

頁面在拿到JSON字元串響應體的時候,是無法識别的,是以需要把JSON字元串轉換為js對象,有兩種方式:

(1)手動把JSON字元串轉換為js對象

借助

JSON.parse(xhr.response)

let data = JSON.parse(xhr.response);
console.log(data);  //js對象:{ name: 'ht' }
result.innerHTML = data.name;
           

(2)自動把JSON字元串轉換為js對象

借助

xhr.responseType = 'json';

xhr.responseType = 'json';
......
console.log(xhr.response); //js對象:{ name: 'ht' }
result.innerHTML = xhr.response.name;
           

五、AJAX請求的幾個問題

1.IE緩存問題

//IE緩存問題
app.get('/ie', (request, response) => {
    //設定響應頭
    response.setHeader('Access-Control-Allow-Origin', '*');
    //設定響應體
    response.send('HELLO IE 666');
})
           

惡心的IE當你響應體改變時,它不會更新,而是走緩存,想要解決這個問題,就要讓每次請求的url都不一樣,那麼我們在後面傳個參數,值為時間戳,就可以解決改變響應體時IE走緩存不更新的問題

2.AJAX請求逾時與網絡異常處理

服務端寫個定時器,2秒後發送響應體過去

app.get('/delay', (request, response) => {
    //設定響應頭
    response.setHeader('Access-Control-Allow-Origin', '*');
    //設定響應體
    setTimeout(() => {
        response.send('HELLO 我延遲響應啦');
    }, 2000);
})
           

然後點選按鈕發送請求時,可以設定逾時

xhr.timeout

和逾時回調

xhr.ontimeout

,還有網絡異常回調

xhr.onerror

const xhr = new XMLHttpRequest();
//逾時設定,1s還沒收到響應體,就取消請求
xhr.timeout = 1000;
//逾時回調
xhr.ontimeout = function() {
    alert('請求逾時baby!');
}
//網絡異常回調
xhr.onerror = function () {
    alert('你的網絡似乎開小差了!!'); 
}
           

Chorme浏覽器可以手動斷網

AJAX(一):初識AJAX、http協定、配置環境、發送AJAX請求、請求時的問題一、什麼是AJAX?二、HTTP協定三、AJAX案例準備工作四、發送AJAX請求五、AJAX請求的幾個問題

3.AJAX手動取消請求

還是搞個定時器發送響應體

app.get('/cancel', (request, response) => {
    //設定響應頭
    response.setHeader('Access-Control-Allow-Origin', '*');
    //設定響應體
    setTimeout(() => {
        response.send('HELLO 我請求被取消了,沒法發過去了');
    }, 2000);
})
           

整倆按鈕

<button>點選發送請求</button>
<button>點選取消請求</button>
           

取消請求,用

xhr.abort()

方法,abort中文意思是中止

這裡邊兒有個作用域的問題,解決方法是把xhr定義在外邊給個null,然後指派xhr執行個體,再調用方法。(重複指派不要用const噢,能用const就用const,不能const就let,反正别var揍中了)

const send = document.querySelectorAll('button')[0];
const cancel = document.querySelectorAll('button')[1];

let xhr = null;
//發送請求
send.onclick = function() {
    xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://127.0.0.1:8000/cancel');
    xhr.send();  //不用拿響應體,是以後邊兒不寫了
}
//取消請求,abort方法
cancel.addEventListener('click', function() {
    xhr.abort(); //先點send再點cancel不會報錯,先點cancel報錯
    console.log(xhr);  //先點send再點cancel是xhr執行個體,先點cancel報錯
})
           

4.AJAX請求重複發送問題

服務端還是用的前面的定時器,這裡重複請求寫個邏輯,如果沒處在請求中,就建立新的請求;如果已經請求了,就廢掉,再重新建立請求。具體看代碼和注釋吧,這塊兒聽的不是很清晰,先簡單了解下,還有啊,作用域回頭得補補,這塊兒太不熟了

const send = document.querySelector('button');

let xhr = null;
let isSending = false;  //是否正在發送AJAX請求
//發送請求
send.onclick = function() {
    //如果沒處在請求中,就建立新的請求;如果已經請求了,就廢掉,再重新建立請求
    if(isSending) xhr.abort();    
    xhr = new XMLHttpRequest();
    isSending = true;
    xhr.open('GET', 'http://127.0.0.1:8000/delay');
    xhr.send();
    xhr.onreadystatechange = function() {
        if(xhr.readyState === 4) {
            //有可能請求失敗,是以這裡不用再做判斷,隻要拿到結果,就算請求完成
            isSending = false;  //拿到伺服器的全部結果後,置為false
        }
    }
}
           

繼續閱讀