簡單聊一聊怎麼用ajax來進行互動

2022-02-08 19:00:26
本篇文章給大家帶來了關於ajax進行互動的相關知識,其中包括同步非同步、回撥函數、promise的使用等等相關問題,希望對大家有幫助。

同步和非同步

同步: 指的就是事情要一件一件做。等做完前一件才能做後一件任務

非同步: 不受當前任務的影響,兩件事情同時進行,做一件事情時,不影響另一件事情的進行。

程式設計中:非同步程式程式碼執行時不會阻塞其它程式程式碼執行,從而提升整體執行效率。

在這裡插入圖片描述

ajax的概念

什麼是ajax

1 Ajax: asynchronous javascript and xml (非同步js和xml)

2 是可以與伺服器進行(非同步/同步)互動的技術之一。

ajax的語言載體是javascript。 最大特點:頁面不重新整理
ajax的一些常見應用,使網頁無重新整理向web伺服器傳送請求資料.

在這裡插入圖片描述

在這裡插入圖片描述

ajax出現的歷史

1999年,微軟公司釋出IE5瀏覽器的時候嵌入的一種技術。起初名字是XMLHttp
直到2005年,google公司釋出了一個郵箱產品gmail,內部有使用ajax技術,該事情引起人們對ajax的注意,也使得一蹶不振的javascript語言從此被人們重視起來

ajax的使用

XMLHttpRequest物件

瀏覽器內建物件,用於與伺服器通訊(交換資料) , 由此我們便可實現對網頁的部分更新,而不是重新整理整個頁面。這個請求是非同步的,即在往伺服器傳送請求時,並不會阻礙程式的執行,瀏覽器會繼續渲染後續的結構。

ajax的執行

一定要開啟phpsudy,js檔案與php檔案在同一主機下,才能請求成功.

GET請求的建立

請求的建立與傳送

主流瀏覽器(火狐、google、蘋果safari、opera,包括IE8以上的版本)的建立方式,也是現在主要使用的.

//1. 建立一個XMLHttpRequest物件var xhr = new XMLHttpRequest();
//2. 設定請求的型別,以及地址
// 第一個引數:請求方式  get/post
// 第二個引數:請求的地址 需要在url後面拼上參數列
// 第三個引數:預設是非同步xhr.open("get", "01.php?name=Jepson",非同步/同步);
//3.傳送請求到伺服器xhr.send(null);

手冊位置

http://www.w3school.com.cn/ajax/ajax_xmlhttprequest_create.asp

GET的使用

例1:在頁面中新增一個按鈕,點選一次向php後臺傳送一個請求,php將一段文字寫入a.txt

<body>
    <input type="button" onclick="fn()" value="點選傳送ajax" />
    <script>
    function fn(){
            // 1 範例化物件
            let xhr = new XMLHttpRequest();
        // 2 設定請求的型別以及地址
        xhr.open('get','./02.php');
        // 3 傳送請求,get請求則設定為空,post請求則設定引數
        xhr.send();
    }

    </script></body>

php程式碼如下

<?php$str  = '越懶散,越懶!';$file = './a.txt';$f = fopen($file,'a');
  fwrite($f,$str);?>
ajax狀態

通過監控請求狀態,當狀態等於4的時候才能接受資料

xhrObj.onreadystatechange - 監聽readyState狀態,當狀態發生改變可呼叫對應函數處理

ajax五種狀態的作用

/*xhrObj.readyState - 返回當前請求的狀態
xhr.readyState = 0時-未初始化,物件已建立,尚未呼叫open()
xhr.readyState = 1時-初始化,物件建立未呼叫send()
xhr.readyState = 2時-傳送資料,send()方法呼叫,但是當前的狀態及http頭未知,請求未完成
xhr.readyState = 3時-資料傳輸中,接受部分資料
xhr.readyState = 4時-響應內容解析完成
*/

例:獲取ajax請求過程的四種狀態

    // 1 範例化物件
  let xhr = new XMLHttpRequest(); 
     xhr.onreadystatechange = function(){
          // 4 使用回撥函數檢測當前的狀態
                console.log(xhr.readyState);
                // 獲取伺服器狀態碼
                console.log(xhr.status)
                // 接受伺服器返回資料
               console.log(xhr.responseText);  
     }
    //  2 建立請求
     xhr.open('get','http://localhost/web/index.php');
     // 3 傳送請求
     xhr.send();

在這裡插入圖片描述

返回伺服器狀態碼 xhr.status

1**:請求收到,繼續處理
2**:操作成功收到,分析、接受
3**:完成此請求必須進一步處理
4**:請求包含一個錯誤語法或不能完成
5**:伺服器執行一個完全有效請求失敗

100——客戶必須繼續發出請求
101——客戶要求伺服器根據請求轉換HTTP協定版本

200——使用者端請求成功
201——提示知道新檔案的URL     
202——接受和處理、但處理未完成
203——返回資訊不確定或不完整
204——請求收到,但返回資訊為空
205——伺服器完成了請求,使用者代理必須復位當前已經瀏覽過的檔案
206——伺服器已經完成了部分使用者的GET請求

300——請求的資源可在多處得到
301——刪除請求資料
302——在其他地址發現了請求資料
303——建議客戶存取其他URL或存取方式
304——使用者端已經執行了GET,但檔案未變化
305——請求的資源必須從伺服器指定的地址得到
306——前一版本HTTP中使用的程式碼,現行版本中不再使用
307——申明請求的資源臨時性刪除

400——錯誤請求,如語法錯誤
401——請求授權失敗
402——保留有效ChargeTo頭響應
403——請求不允許
404——沒有發現檔案、查詢或URl
405——使用者在Request-Line欄位定義的方法不允許
406——根據使用者傳送的Accept拖,請求資源不可存取
407——類似401,使用者必須首先在代理伺服器上得到授權
408——使用者端沒有在使用者指定的餓時間內完成請求
409——對當前資源狀態,請求不能完成
410——伺服器上不再有此資源且無進一步的參考地址
411——伺服器拒絕使用者定義的Content-Length屬性請求
412——一個或多個請求頭欄位在當前請求中錯誤
413——請求的資源大於伺服器允許的大小
414——請求的資源URL長於伺服器允許的長度
415——請求資源不支援請求專案格式
416——請求中包含Range請求頭欄位,在當前請求資源範圍內沒有range指示值,請求也不包含If-Range請求頭欄位
417——伺服器不滿足請求Expect頭欄位指定的期望值,如果是代理伺服器,可能是下一級伺服器不能滿足請求

500——伺服器產生內部錯誤
501——伺服器不支援請求的函數
502——伺服器暫時不可用,有時是為了防止發生系統過載
503——伺服器過載或暫停維修
504——關口過載,伺服器使用另一個關口或服務來響應使用者,等待時間設定值較長
505——伺服器不支援或拒絕支請求頭中指定的HTTP版本
伺服器響應值接收

如需獲得來自伺服器的響應,請使用 XMLHttpRequest 物件的 responseText 或 responseXML 屬性。

屬性描述
response獲得字串形式的響應資料。
responseXML獲得 XML 形式的響應資料(知道)。

接受伺服器返回值

<!DOCTYPE html><html lang="en">
    <head>
        <meta charset="utf-8">
    </head>
    <script type="text/javascript">
      function f1(){
        //建立ajax物件
        var xhr  = new XMLHttpRequest();
        //設定請求的地址
        xhr.open('get','./reponse.php');
        //傳送請求,如果是get請求則引數設定為null
        xhr.send();
        //顯示ajax的狀態
        /*
        ajax的四中狀態
        0 物件已建立,請求連線未初始化(尚未呼叫open方法)
        1 請求連線已經已經建立沒有呼叫send方法
        2 請求連線已建立,呼叫send方法
        3 資料已經開始傳輸但尚未完成
        4 資料傳輸已經完成,請求已經完成
         */
           // onreadystatechange 當請求的狀態發生改變時,就會觸發
        xhr.onreadystatechange=function(){
            //顯示五種狀態
            //console.log(xhr.readyState);
            //判斷當的請求狀態等於4時,代表資料傳輸完成
             if(xhr.readyState==4 && xhr.status==200){
                //使用responseText接受伺服器端傳遞的資料
                //alert(xhr.responseText);
                //追加顯示到頁面中
               document.body.innerHTML+=xhr.responseText;
             }
        }
        
        //alert(xhr.responseText);
      }
    </script>
    <body>
    <input type="button" name="" value="點我傳送請求" onclick="f1();">
    </body></html>

伺服器程式碼

<?php$a = '1234';echo $a;?>

總結:

1 建立物件let xhr = new XMLHttpRequest();2 設定請求

xhr.open(get,請求地址)3 傳送請求

xhr.send()4 判斷狀態接收返回值

xhr.onreadystatechange = funtion(){

   if(xhr.readyState==4 && xhr.status==200){// 接受返回值let str = xhr.response  }}

get和post的區別

1 get是位址列的方式存取的,是可見的

2 get方式傳遞資料量比較小.安全性低.

3 post以非位址列的形式存取,能夠安全且大量的穿遞資料

常見post使用

表單中使用, ajax中使用

POST方式

請求步驟
  1. 建立Ajax物件。

  2. 設定回撥函數。接收後臺返回的結果

  3. 設定請求

  4. 設定請求頭資訊「Content-type,application/x-www-form-urlencoded」

  5. 傳送請求。

實現請求

setRequestHeader() 設定請求頭資訊

application/x-www-form-urlencoded 設定傳遞引數時,使用的編碼格式(預設)

例:以post的方式傳遞資料

<!DOCTYPE html><html lang="en">
    <head>
        <meta charset="utf-8">
    </head>
    <script type="text/javascript">
     function f1(){
        //範例化ajax物件
        var xhr = new XMLHttpRequest();
        //設定請求的引數,設定以post方式傳送請求
        xhr.open('post','./post.php');
         //如果需要像 HTML 表單那樣 POST 資料,以&形式傳輸資料
        xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
        //構造傳遞的引數,形式與get傳參的方式一致
        var data = 'name=張三&age=19';
         //傳送請求
         xhr.send(data);

         //接受返回的資訊
         xhr.onreadystatechange=function(){
            //驗證當前的裝態接受返回的資訊
            if(xhr.readyState==4){
                //接受伺服器返回的信
                var info = xhr.responseText;
                alert(info);
            }
         }
     }
    </script>
    <body>
    <input type="button" name="" value="post請求" onclick="f1();">
    </body></html>

同步和非同步請求

非同步:不等待ajax請求響應完畢,直接執行下面的程式碼

同步:等待ajax請求響應完畢後,再執行下面的程式碼

ajax的非同步

非同步示意圖

在這裡插入圖片描述

ajax的同步

同步請求

在這裡插入圖片描述

驗證同步與非同步

js程式碼

<body>
    <input type="button" onclick="fn()" value="點選傳送ajax" />
    <script>
    function fn(){
         // 1 範例化物件
         let xhr = new XMLHttpRequest();
         // 獲取ajax的四種狀態
         xhr.onreadystatechange = function(state){
             // console.log(xhr.readyState);
              //alert(xhr.responseText)
              if(xhr.readyState==4){
                  console.log(xhr.response)
              }
         }

        // 2 設定請求的型別以及地址,第三個引數設定為false,表示同步,設定為true表示非同步(預設)
        xhr.open('get','http://localhost/demo.php',false);
        // 3 傳送請求,get請求則設定為空,post請求則設定引數
        xhr.send();
        // 驗證同步必須寫的
        console.log(11111);
    }

 //   console.log(eval('{}'));
 //   console.log(eval('({})'));

    </script>

PHP程式碼

<?php$str  = '越懶散,越懶!';$file = './a.txt';$f = fopen($file,'a');
  fwrite($f,$str);
  // 讓程式碼沉睡十秒之後,再向下執行
 sleep(10);
  echo '這是輸出的內容';?>

測試同步請求時,獲取返回結果的responseText一定要放在send()之前

服務返回資料格式處理

型別

Text(又稱HTML格式)

XML格式

JSON格式

Text型別處理

<script type="text/javascript">
      var xhr = new XMLHttpRequest();
           xhr.onreadystatechange = function(){
            if(xhr.readyState==4){
                //接受返回的訊息
                var info =xhr.responseText; 
               alert(info);
            }
           }
      xhr.open('get','./geshi.php');
      xhr.send(null);
    </script>[php程式碼]echo '<h2>完了,就要完了!</h2>';

json資料的處理

使用JOSN.parse()將PHP輸出的json字串轉化為物件

<script type="text/javascript">
      var xhr = new XMLHttpRequest();
           xhr.onreadystatechange = function(){
            if(xhr.readyState==4){
                //接受返回的訊息,
                var info =xhr.responseText; 
                //將json陣列轉化為js物件
                 var str = JSON.parse(info);
                 console.log(str);
            }
           }
      xhr.open('get','./geshi.php');
      xhr.send(null);</script>[PHP程式碼]echo json_encode(array("name"=>'張三',"age"=>'12'));

xml資料的處理

 <script type="text/javascript">
      var xhr = new XMLHttpRequest();
           xhr.onreadystatechange = function(){
            if(xhr.readyState==4){
                //接受返回的訊息,使用responseXML接受
                var info =xhr.responseXML; 
                 var msg=info.getElementsByTagName('msg')[0].innerHTML;
                 console.log(msg);
            }
           }
      xhr.open('get','./geshi.php');
      xhr.send(null);</script>[PHP程式碼]<?phpheader('content-type:text/xml;charset=utf-8');echo '<?xml version="1.0" encoding="utf-8" ?>
      <response>
      <status>1</status>
      <msg>返回的的訊息</msg>
       </response>';

回撥函數的巢狀

概念

回撥函數是一個作為變數傳遞給另外一個函數的函數,它在主體函數執行完之後執行。

正常的程式碼都是鏈式操作,某一步執行出問題,則向下停止,而回撥則不然.

常見的典型非同步回撥

    setTimeout(function(){
        console.log('1s之後做的事情');
        setTimeout(function(){
            console.log('2s之後做的事情');
            setTimeout(function(){
               console.log('3s之後做的事情');
            },1000);
        },1000);
    },1000);

在回撥函數中巢狀,就是上一個函數執行完成,再執行下一個

promise使用

在JavaScript的世界中,所有程式碼都是單執行緒執行的。由於這個「缺陷」,導致JavaScript的所有網路操作,瀏覽器事件,都必須是非同步執行。非同步執行可以用回撥函數實現.

Promise使ES6中引入的一個非同步程式設計解決方案,與傳統的ES5方法相比它的結構更合理,功能更強大.

特點

Promise物件代表一個非同步操作,有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗)。只有非同步操作的結果,可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態.

語法:

  var p = new Promise(function(resolve,reject){})
 resolve 代表 決定(成功); reject 代表 失敗

使用

基本使用

const p  = new Promise(function(resolve,reject){
    setTimeout(function(){
       // resolve('我是成功的')
       reject('這是失敗的');
    },2000)
});

.then(callback)的使用(成功時呼叫)

.catch(callback的用法(失敗時呼叫)

  p.then(function(data){
			console.log('resolved成功回撥');
			console.log('成功回撥接受的值:',data);
		}).catch(function(reason, data){
		    console.log('catch到rejected失敗回撥');
		     console.log('catch失敗執行回撥丟擲失敗原因:',reason);
	});	效果和寫在then的第二個引數裡面一樣。它將大於10的情況下的失敗回撥的原因輸出

注意:resolve和reject的兩種狀態

resolve作用是,將Promise物件的狀態從「未完成」變為「成功」(即從 pending 變為 resolved),在非同步操作成功時呼叫,並將非同步操作的結果,作為引數傳遞出去;

reject作用是,將Promise物件的狀態從「未完成」變為「失敗」(即從 pending 變為 rejected),在非同步操作失敗時呼叫,並將非同步操作報出的錯誤,作為引數傳遞出去。

promise改造ajax依賴呼叫

使用promise檢測ajax的請求狀態,利用promise的成功狀態函數,返回ajax請求到的資料

第一步,將ajax進行封裝

    const ajaxParam=param=>{
        return new Promise(function(resolve,reject){
            let xhr = new XMLHttpRequest();
        
              xhr.open('get',param.url); // 預設是true,表示非同步
      
              xhr.send();
              xhr.onreadystatechange = function(){
                  if(xhr.readyState==4 ){
                      if(xhr.status==200){
                          resolve(xhr.responseText)
                      }else{
                          reject(xhr.responseText)
                      }

                  }
              }
        });

    }

第二步:使用then和catch獲取結果,

      ajaxPromise({type:'get',url:'http//:www.baidu.com',data:null}).then(function(data){
          
      }).catch(function(data){
          
      });

擴充套件:

Promise.all()

所有的非同步請求完成才執行的方法.

Promse.all在處理多個非同步處理時非常有用,比如說一個頁面上需要等兩個或多個ajax的資料回來以後才正常顯示,在此之前只顯示loading圖示。

let wake = (time) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`${time / 1000}秒後醒來`)
    }, time)
  })}let p1 = wake(3000);let p2 = wake(2000);Promise.all([p1, p2]).then((result) => {
  console.log(result)       // [ '3秒後醒來', '2秒後醒來' ]}).catch((error) => {
  console.log(error)})只有兩次呼叫promise都執行完畢,才會執行all

Promise.race()

Promse.race就是賽跑的意思,意思就是說,Promise.race([p1, p2, p3])裡面哪個結果獲得的快,就返回那個結果,不管結果本身是成功狀態還是失敗狀態。

let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success')
  },1000)})let p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('failed')
  }, 500)})Promise.race([p1, p2]).then((result) => {
  console.log(result)}).catch((error) => {
  console.log(error)  // 開啟的是 'failed'})

【相關教學推薦:AJAX視訊教學

以上就是簡單聊一聊怎麼用ajax來進行互動的詳細內容,更多請關注TW511.COM其它相關文章!