欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript中前后端交互Ajax示例詳解

 更新時(shí)間:2024年03月21日 09:48:37   作者:mmaqzxc  
Ajax不是一種新的編程語(yǔ)言,而是使用現(xiàn)有標(biāo)準(zhǔn)的新方法,下面這篇文章主要給大家介紹了關(guān)于JavaScript中前后端交互Ajax的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

1、Ajax概述

(1)什么是Ajax

Ajax:Asynchronous JavaScript And XML,異步JavaScript和XML技術(shù)。

描述:不是一門新的語(yǔ)言或技術(shù),是由JavaScript、XML、DOM、CSS等多種已有技術(shù)組合而成的一種瀏覽器端技術(shù)。

功能:用于實(shí)現(xiàn)與服務(wù)器進(jìn)行異步交互的功能。用js來實(shí)現(xiàn)頁(yè)面的局部刷新。

(2)Ajax工作流程

2、前后端交互-Ajax

(1)創(chuàng)建Ajax對(duì)象

<script>
//W3C標(biāo)準(zhǔn)
  var xhr = new XMLHttpRequest();
</script>

<script>
//早期IE瀏覽器
  var xhr = new ActiveXObject('Microsoft.XMLHTTP');
  var xhr = new ActiveXObject('Msxml2.XMLHTTP');
  var xhr = new ActiveXObject('Msxml2.XMLHTTP.3.0');
  var xhr = new ActiveXObject('Msxml2.XMLHTTP.5.0');
  var xhr = new ActiveXObject('Msxml2.XMLHTTP.6.0');
</script>

(2)Ajax向服務(wù)器發(fā)送請(qǐng)求

open(‘method’, ‘URL’ [, asyncFlag [, ‘userName’ [, ‘password’]]])

  • method:用于指定請(qǐng)求方式,如GET、POST,不區(qū)分大小寫。
  • URL:表示請(qǐng)求的地址。
  • asyncFlag:可選參數(shù),用于指定請(qǐng)求方式,同步請(qǐng)求為false,默認(rèn)為異步請(qǐng)求true。
  • userName和password:可選參數(shù),表示HTTP認(rèn)證的用戶名和密碼。

send(content)

  • content:用于指定要發(fā)送的數(shù)據(jù),其值可為DOM對(duì)象的實(shí)例、輸入流或字符串,一般與POST請(qǐng)求類型配合使用。
  • 注意:如果請(qǐng)求聲明為同步,該方法將會(huì)等待請(qǐng)求完成或者超時(shí)才會(huì)返回,否則此方法將立即返回。

setRequestHeader(‘haeder’, ‘value’)

  • 參數(shù)都為字符串類型。
  • header表示請(qǐng)求頭字段。
  • value為該字段的值。
  • 此方法必須在open()方法后調(diào)用。
<script>
    // 1、創(chuàng)建ajax對(duì)象
    var xhr = new XMLHttpRequest();
    // 2、建立http請(qǐng)求
    xhr.open('GET','test.php?a=1&b=2');
    // 3、發(fā)送請(qǐng)求到web服務(wù)器并接收響應(yīng)
    xhr.send();
</script>
<!-- get:適合從服務(wù)器獲取數(shù)據(jù) -->
<script>
    // 1、創(chuàng)建ajax對(duì)象
    var xhr = new XMLHttpRequest();
    // 2、建立http請(qǐng)求
    xhr.open('POST','test.php?a=1&b=2');
    // 3、請(qǐng)求頭內(nèi)指定實(shí)體內(nèi)容的編碼格式
    xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
    // 4、發(fā)送請(qǐng)求到web服務(wù)器并接收響應(yīng)
    xhr.send('c=3&d=4');
</script>
<!-- POST:適合向服務(wù)器發(fā)生數(shù)據(jù) -->
  • 在進(jìn)行Ajax開發(fā)時(shí),經(jīng)常使用GET方式或POST方式發(fā)送請(qǐng)求。
  • GET方式適合從服務(wù)器獲取數(shù)據(jù)。
  • POST方式適合向服務(wù)器發(fā)送數(shù)據(jù)。需要設(shè)置內(nèi)容的編碼格式,告知服務(wù)器用什么樣的格式來解析數(shù)據(jù)。

注意:同步請(qǐng)求與異步請(qǐng)求

Ajax對(duì)象open()方法的第3個(gè)參數(shù)用于設(shè)置同步請(qǐng)求和異步請(qǐng)求。

兩種方式的區(qū)別在于,是否阻塞代碼的執(zhí)行。

異步方式(默認(rèn)):是非阻塞的,瀏覽器端的JavaScript程序不用等待Web服務(wù)器響應(yīng),可以繼續(xù)處理其他事情。當(dāng)服務(wù)器響應(yīng)后,再來處理Ajax對(duì)象獲取到的響應(yīng)結(jié)果。

同步方式:是阻塞的,當(dāng)Ajax對(duì)象向Web服務(wù)器發(fā)送請(qǐng)求后,會(huì)等待Web服務(wù)器響應(yīng)的數(shù)據(jù)接收完成,再繼續(xù)執(zhí)行后面的代碼。

(3)處理服務(wù)器返回的信息

a、readyState屬性用于獲取Ajax的當(dāng)前狀態(tài),狀態(tài)值有5種形式。

Ajax狀態(tài)的還可以通過“XMLHttpRequest.屬性名”的方式獲取。

<script>
  XMLHttpRequest.UNSENT;                    // 對(duì)應(yīng)狀態(tài)值0
  XMLHttpRequest.OPENED;                    // 對(duì)應(yīng)狀態(tài)值1
  XMLHttpRequest.HEADERS_RECEIVED;          // 對(duì)應(yīng)狀態(tài)值2
  XMLHttpRequest.LOADING;                   // 對(duì)應(yīng)狀態(tài)值3
  XMLHttpRequest.DONE;                      // 對(duì)應(yīng)狀態(tài)值4
</script>

b、onreadystatechange事件屬性用于感知readyState屬性狀態(tài)的改變,每當(dāng)readyState的值發(fā)生改變時(shí),就會(huì)調(diào)用此事件。

<script>
    // 1、創(chuàng)建ajax對(duì)象
    var xhr = new XMLHttpRequest()
    console.log(xhr.readyState)//0
    xhr.onreadystatechange = function(){
        console.log(xhr.readyState)//1,2,3,4
    }
    xhr.open('get','test.php')
    xhr.send()
</script>

c、status屬性用于返回當(dāng)前請(qǐng)求的HTTP狀態(tài)碼,值為數(shù)值類型。

例如,當(dāng)請(qǐng)求成功時(shí),狀態(tài)碼為200。

另外還有一個(gè)類似的屬性statusText,值為字符型數(shù)據(jù),包含了描述短語(yǔ),如“200 OK”。

d、獲取服務(wù)器的響應(yīng)信息

responseXML屬性在請(qǐng)求失敗或相應(yīng)內(nèi)容無法解析時(shí)的值為null。

需要注意的是,服務(wù)器在返回XML時(shí)應(yīng)設(shè)置響應(yīng)頭Content-Type的值為text/xml或application/xml,否則會(huì)解析失敗。

<script>
    // 1、創(chuàng)建對(duì)象
    var xhr = new XMLHttpRequest();
    // 2、事件屬性
    xhr.onreadystatechange = function(){
        // xhr.readyState 獲取狀態(tài)值 1,2,3,4
        if(xhr.readyState === XMLHttpRequest.DONE){
            // status 響應(yīng)狀態(tài)碼
            if(xhr.status<200 || xhr.status>=300 && xhr.status !== 304){
                alert('服務(wù)器異常');
                return;
            }
            // xhr.responseText //Hello
            console.log(xhr.responseText)
            document.write('<h2>'+xhr.responseText+'</h2>')
        }
    }
    xhr.open('get','hello.php')
    xhr.send()
</script>

注意:URL參數(shù)編碼轉(zhuǎn)換

<script>
  var str = encodeURIComponent('A&B C');
  var url = 'http://xxx/test.php?name=' + str;
  console.log(url);                        // 輸出結(jié)果:http://xxx/test.php?name=A%26B%20C
</script>

<script>
  var str = 'A%26B%20C';
  console.log(decodeURIComponent(str));    // 輸出結(jié)果:A&B C
</script>

3、前后端交互-數(shù)據(jù)格式

前后端約定一種格式,確保通信雙方都能夠正確識(shí)別對(duì)方發(fā)送的信息。

(1)XML

XML:eXtensible Markup Language,可擴(kuò)展標(biāo)記語(yǔ)言。

與HTML都是標(biāo)簽語(yǔ)言,XML主要用于描述和存儲(chǔ)數(shù)據(jù),可以自定義標(biāo)簽。

當(dāng)服務(wù)器返回的是一個(gè)XML格式的數(shù)據(jù)時(shí),利用Ajax對(duì)象的responseXML屬性即可對(duì)XML數(shù)據(jù)進(jìn)行處理。

<script>
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function(){
        if(xhr.readyState === XMLHttpRequest.DONE){
            var data = xhr.responseXML;
            var booklist = data.getElementsByTagName('booklist')[0];//<booklist>...</booklist>
            console.log(booklist.childNodes)//[text\book\text]
            console.log(booklist.children)//[book]
            var book = booklist.children[0]//<book>...</book>
            console.log(book.children)//[name,author]
            console.log(book.children[0].innerHTML)//西游記
            console.log(book.children[0].firstChild)// '西游記'
            console.log(book.children[0].firstChild.wholeText)//西游記
        }
    }
    xhr.open('get','xml.php')
    xhr.send()
</script>

(2)JSON

JSON:是一種輕量級(jí)的數(shù)據(jù)交換格式。

特點(diǎn):采用完全獨(dú)立于語(yǔ)言的文本格式,這使得JSON更易于程序的解析和處理。

與XML對(duì)比:使用JSON對(duì)象訪問屬性的方式獲取數(shù)據(jù)更加方便,在JavaScript中可以輕松地在JSON字符串與對(duì)象之間轉(zhuǎn)換。

<script>
    var obj = {name:'Tom',age:21} //準(zhǔn)備要發(fā)生的數(shù)據(jù)
    var json = JSON.stringify(obj)//將obj對(duì)象轉(zhuǎn)換為json字符串
    var xhr = new XMLHttpRequest();//創(chuàng)建ajax對(duì)象
    xhr.open('post','json.php');//建立連接

    xhr.onreadystatechange = function(){
        if(xhr.readyState === XMLHttpRequest.DONE){
            console.log(typeof xhr.responseText)//查看服務(wù)器返回的數(shù)據(jù)類型:string
            var obj = JSON.parse(xhr.responseText)//將json字符串轉(zhuǎn)換為對(duì)象
            console.log(obj)
            // eval() 將傳入的字符串當(dāng)js代碼執(zhí)行
            eval("var obj="+xhr.responseText)//用eval函數(shù)將字符型轉(zhuǎn)換為對(duì)象
            console.log(obj.name)
            console.log(obj.age)
        }
    }
    xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
    xhr.send('json='+encodeURIComponent(json))//發(fā)送請(qǐng)求
</script>

4、前后端交互-跨域請(qǐng)求

域(Domain)是指網(wǎng)絡(luò)中獨(dú)立運(yùn)行的單位。

從網(wǎng)絡(luò)安全角度來看,域是安全的邊界,每個(gè)域都有自己的安全策略,不同域之間是隔離的,除非建立信任關(guān)系,否則無法互相訪問。

什么是跨域:未遵循同源策略,同源是指請(qǐng)求URL地址中的協(xié)議、域名和端口都相同

跨域請(qǐng)求會(huì)導(dǎo)致網(wǎng)頁(yè)失去安全性,因此瀏覽器阻止跨域請(qǐng)求。

(1)Access-Control-Allow-Origin響應(yīng)頭

解決辦法之一:為使受信任的網(wǎng)站之間能夠跨域訪問,HTML5提供了一個(gè)新的策略,就是Access-Control-Allow-Origin響應(yīng)頭。目標(biāo)服務(wù)器通過該響應(yīng)頭可以指定允許來自特定URL的跨域請(qǐng)求,其值可以設(shè)置為任意URL或特定URL等。

(2)JSONP實(shí)現(xiàn)跨域請(qǐng)求

JSONP:遵循瀏覽器的同源策略基礎(chǔ)上實(shí)現(xiàn)跨域請(qǐng)求的一種方式。

原理:與XMLHttpRequest無關(guān),是利用

JSONP之所以采用<script>標(biāo)簽,是因?yàn)樵摌?biāo)簽加載的資源可以直接當(dāng)做JavaScript代碼執(zhí)行,只要通過服務(wù)器端的配合,就可以傳送數(shù)據(jù)。

JSONP跨域請(qǐng)求。

JSONP本質(zhì)上是加載了其他網(wǎng)站的腳本,這種方式存在安全風(fēng)險(xiǎn),因?yàn)?/p>

其他網(wǎng)站可以利用JavaScript竊取用戶信息,或更改頁(yè)面內(nèi)容。因此,在加載腳本前,一定確保對(duì)方是受信任的網(wǎng)站。

5、其他

(1)Cookie

Cookie:或稱為Cookies,指某些網(wǎng)站為了辨別用戶身份、進(jìn)行會(huì)話(Session)跟蹤而儲(chǔ)存在客戶端上的數(shù)據(jù)。

相關(guān)的響應(yīng)頭:Set-Cookie字段

特點(diǎn):下次請(qǐng)求該網(wǎng)站時(shí),瀏覽器會(huì)將Cookie數(shù)據(jù)放入請(qǐng)求頭中的Cookie字段,服務(wù)器收到這段數(shù)據(jù)即可辨認(rèn)用戶狀態(tài)。

Cookie是根據(jù)域名、路徑等參數(shù)存儲(chǔ)的,不同網(wǎng)站的Cookie相互隔離,從而保證數(shù)據(jù)的安全性。

(2)FormData

Ajax向服務(wù)器發(fā)送數(shù)據(jù)時(shí),可以通過FormData收集表單中的數(shù)據(jù)。

使用方式:new FormData()實(shí)例化并傳入表單對(duì)象即可。在創(chuàng)建FormData對(duì)象后,可在調(diào)用Ajax對(duì)象的send()方法時(shí)作為參數(shù)傳入,從而將表單數(shù)據(jù)發(fā)送給服務(wù)器。

<form id="form">
    姓名:<input type="text" name="name"><br>
    密碼:<input type="password" name="pass"><br>
    郵箱:<input type="text" name="email"><br>
    <input type="submit" value="提交">
</form>
<script>
    document.getElementById('form').onsubmit = function(){
        var fd = new FormData(this);
        // 1、創(chuàng)建ajax對(duì)象
        var xhr = new XMLHttpRequest()
        // 2、建立http請(qǐng)求
        xhr.open('post','test.php')
        // 3、發(fā)送請(qǐng)求
        xhr.send(fd)
        return false;//阻止表單默認(rèn)的提交操作
    }
</script>

<script>
    var fd = new FormData();
    fd.append('','')
</script>

(3)Promise

Promise是ES6新增的對(duì)象,用來傳遞異步操作的消息。

在代碼層面,Promise解決了異步操作的“回調(diào)地獄”問題。

回調(diào)地獄”是指,在一個(gè)異步操作執(zhí)行完成后,執(zhí)行下一個(gè)異步操作時(shí),出現(xiàn)回調(diào)函數(shù)嵌套回調(diào)函數(shù)的情況。如果嵌套的層級(jí)過多,會(huì)導(dǎo)致代碼可讀性變差,下面的代碼演示了這種情況。

Ajax的onreadystatechange()就是一個(gè)異步操作,若需要在一個(gè)Ajax請(qǐng)求完成后,再發(fā)出另一個(gè)Ajax請(qǐng)求,就會(huì)出現(xiàn)回調(diào)函數(shù)嵌套情況。

<script>
  function xhr(options) {
    return new Promise(function(resolve, reject) {
      var xhr = new XMLHttpRequest();
      xhr.open(options.type || 'GET', options.url);
      xhr.onreadystatechange = function() {
        if (xhr.readyState === XMLHttpRequest.DONE) {
          if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
            resolve(xhr.responseText);     // 成功時(shí)執(zhí)行的函數(shù)
          } else {
            reject('服務(wù)器發(fā)生錯(cuò)誤。');    // 失敗時(shí)執(zhí)行的函數(shù)
          }
        }
      };
      xhr.send(options.data);
    });
  }
  
  var fd = new FormData();
  fd.append('num', 100);
  
  xhr({url: 'test.php', type: 'POST', data: fd})
  .then(function(data) {
    console.log('請(qǐng)求成功:' + data);
  }, function(err) {
    console.log('請(qǐng)求失敗:' + err);
  });
  
  xhr({url: '1.txt', type: 'POST', data: fd})
  .then(function(data) {
    console.log('請(qǐng)求成功:' + data);
  })
  .catch(function(err) {
    console.log('發(fā)生異常:' + err);
  });
  
  xhr({url: 'test.php', type: 'POST', data: fd})
  .then(function(data) {
    console.log('第1次請(qǐng)求結(jié)果:' + data);
    return xhr({url: 'test.php', type: 'POST', data: fd});
  })
  .then(function(data) {
    console.log('第2次請(qǐng)求結(jié)果:' + data);
  })
  .catch(function(err) {
    console.log('發(fā)生異常:' + err);
  });
</script>

(4)WebSocket

WebSocket:是HTML5新增的一個(gè)客戶端與服務(wù)器異步通信的API。

作用:用于使瀏覽器支持WebSocket網(wǎng)絡(luò)協(xié)議。

解決的問題: HTTP輪詢。

HTTP輪詢:客戶端需要不斷向服務(wù)器發(fā)送HTTP請(qǐng)求,詢問服務(wù)器是否有新的消息,這種方式稱為HTTP輪詢。特點(diǎn)是其通信效率非常低。

解決辦法:WebSocket實(shí)現(xiàn)了全雙工通信,在建立連接后,服務(wù)器可以將新消息主動(dòng)推送給客戶端,這種方式實(shí)時(shí)性更強(qiáng),效率更高。

示例1:

<script>
  // 創(chuàng)建WebSocket對(duì)象,連接服務(wù)器
  var ws = new WebSocket('ws://127.0.0.1:2000'); 
  // 當(dāng)連接成功時(shí)執(zhí)行的回調(diào)函數(shù)
  ws.onopen = function() { 
    console.log('連接成功');
    ws.send('Tom');
    console.log('向服務(wù)端發(fā)送一個(gè)字符串:Tom');
  };
  // 當(dāng)收到服務(wù)器消息時(shí)執(zhí)行的回調(diào)函數(shù),event是事件對(duì)象
   ws.onmessage = function(event) {
     console.log('收到服務(wù)器消息:' + event.data);
   };
</script>
<?php
  // 載入Workerman
  use Workerman\Worker;
  require_once __DIR__ . '/workerman-for-win-master/Autoloader.php';
  // 創(chuàng)建一個(gè)Worker監(jiān)聽2000端口,使用WebSocket協(xié)議通訊
  $ws_worker = new Worker('websocket://127.0.0.1:2000');
  // 啟動(dòng)4個(gè)進(jìn)程對(duì)外提供服務(wù)
  $ws_worker->count = 4;
  // 當(dāng)收到客戶端發(fā)來的數(shù)據(jù)$data后返回給客戶端
  $ws_worker->onMessage = function($connection, $data) {
    // 向客戶端發(fā)送Hello $data
    $connection->send('Hello ' . $data);
  };
  // 運(yùn)行Worker
  Worker::runAll();

示例2:

<script>
  var ws = new WebSocket('ws://127.0.0.1:2000');
  ws.onopen = function() {
    console.log('連接成功');
  };
  ws.onmessage = function(e) {
    console.log('收到服務(wù)器消息:' + e.data);
  };
</script>
<?php
  use Workerman\Worker;
  use Workerman\Lib\Timer;
  require_once __DIR__ . '/workerman-for-win-master/Autoloader.php';
  $worker = new Worker('websocket://127.0.0.1:2000');
  // 進(jìn)程啟動(dòng)時(shí)設(shè)置一個(gè)定時(shí)器,定時(shí)向所有客戶端連接發(fā)送數(shù)據(jù)
  $worker->onWorkerStart = function($worker) {
    // 每2秒一次,遍歷當(dāng)前進(jìn)程所有的客戶端連接,發(fā)送當(dāng)前服務(wù)器的時(shí)間
    Timer::add(2, function() use($worker) {
      foreach($worker->connections as $connection) {
        $connection->send(time());
      }
    });
  };
  Worker::runAll();

總結(jié) 

到此這篇關(guān)于JavaScript中前后端交互Ajax的文章就介紹到這了,更多相關(guān)JS前后端交互Ajax內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論