Ajax-使用教程
- 2020 年 4 月 4 日
- 筆記
運行環境
ajax一定的是運行在網站伺服器裡面,因此你需要自己配置nodejs伺服器
導學:傳統的問題還有代理人ajax
傳統的http中是又瀏覽器來做。它在發生和響應的時候網頁是不能進行其他操作的
而ajax是一個中間人
簡單的使用
XMLHTTPRequest是一個內置構造函數,我們創建衣這個的實例就是在創建這個代理人
new 對象
告訴ajax請求的方式還有地址
發送請求
獲取服務端的回送數據沒注意,當對象的onlad就是載入完之後 我們給一個回調來處理數據
數據哪兒來的?是對象下面的responeText來的
創建一個html頁面
01XXX.HTML在這個頁面寫一個ajax並且向伺服器拿數據
<script type="text/javascript"> //需求:通過這個網頁 我們向伺服器發起請求 // 1.創建ajax對象,實例化一個對象出來 let xhr = new XMLHttpRequest(); // 1.穿件一個ajax對象 /* 筆記 告訴ajax對象 向哪兒發送請求,以什麼方式發送請求 xhr.open('get'.'http://localhoset:3030/frist') 發送請求 調用方法xhr.send() 40獲取響應的數據xhr.onload = function() { console.log(xhr.responseText); } 2.告訴Ajax對象要向哪發送請求,以什麼方式發送請求 1)請求方式 2)請求地址 */ //2.告訴ajax發給誰 用什麼發 xhr.open('get', 'http://localhost:3000/first'); //這裡的first是一個路由,我們在伺服器弄一個路由地址就完事 // 3.發送請求 xhr.send(); // 4.獲取伺服器端響應到客戶端的數據,我們需要弄一個回調,onlad事件就是ajax響應到伺服器的數據之後 就能響應這個數據了 xhr.onload = function() { console.log(xhr.responseText) //這個拿到的就是這個東西了數據 } </script>
然後我們去伺服器端配置出來
注意:伺服器列舉了一些順序 你必須要做的
app.js
// 1. 引入express框架 const express = require('express'); // 2. 路徑處理模組 const path = require('path'); // 3. 創建web伺服器 const app = express(); // 4. 靜態資源訪問服務功能,user方法 攔截調所有的請求,如何用框架的static靜態方法,把文件請求到向我們的指定的目錄,我們的文件夾定義為了public app.use(express.static(path.join(__dirname, 'public'))); /* 6 開始設置各種設置各種路由 */ // 對應01html文件 // 6.1 創建第一個響應的數據: app.get(參數1:路由地址,參數2:伺服器的響應函數) app.get('/first', (req, res) => { //這個意思就send'發回去 res.send('Hello, Ajax'); }); // 5.監聽埠 app.listen(3550); // 控制台提示輸出 console.log('伺服器啟動成功');
伺服器返回JSON對象的情況
我們在開發的時候 伺服器一般都是發生JSON對象。如何在前端使用DOM渲染數據就完事
- 02.XXXX.HTML這個頁面用來處理伺服器的json數據
注意啊,在http傳輸中都是字元串的形式傳輸的,為了在網頁中使用字元串,我們需要把它轉化為對象 JSON.parse( 要轉化的字元串 ),返回的數據就是一個對象就完事了
<script type="text/javascript"> // 1.創建ajax對象 var xhr = new XMLHttpRequest(); // 2.告訴Ajax對象要向哪發送請求,以什麼方式發送請求 // 1)請求方式 2)請求地址 xhr.open('get', 'http://localhost:3000/responseData'); // 3.發送請求 xhr.send(); // 4.獲取伺服器端響應到客戶端的數據 xhr.onload = function() { // console.log(typeof xhr.responseText),返回的數據是字元型類型。在http中,無論是什麼,到傳輸中都是字元串傳輸 // 將JSON字元串轉換為JSON對象,json對象的轉換 var responseText = JSON.parse(xhr.responseText); // var responseText = JSON.parse(xhr.XMLHttpRequest); // 測試:在控制台輸出處理結果, console.log(responseText) // DOM操作 var str = '<h2>' + responseText.name + '</h2>'; // 將拼接的結果追加到頁面中 document.body.innerHTML = str; }
- app.js服務端
// 3.2 對應02html文件 app.get('/responseData', (req, res) => { res.send({ "name": "bm" }); //這個是響應一段jison對象, });
傳遞參數之——GET傳遞參數
我們來看一下傳遞參數
傳統的網站get的參數在url中post在請求體當中,參數名詞=參數值,多個參數用&分割
- 03.xxxxxhtml
需求:點擊提交表單 ,發送給伺服器
<body> <p> <input type="text" id="username"> </p> <p> <input type="text" id="age"> </p> <p> <input type="button" value="提交" id="btn"> </p> </body> <script type="text/javascript"> //需求點擊按鈕的時候發送表單對象給伺服器 //1.事件源 var btn = document.getElementById('btn'); //獲取元素,綁定事件 var username = document.getElementById('username'); var age = document.getElementById('age'); // 2.綁定事件 btn.onclick = function() { //3.事件處理程式 // 3.1 創建ajax對象 var xhr = new XMLHttpRequest(); // 3.2 獲取用戶在文本框中輸入的值 var nameValue = username.value; var ageValue = age.value; // 3.3 再ajax中需要進行拼接請求參數。我們在這裡還是得使用拼接的方式,發送請求 var params = 'username=' + nameValue + '&age=' + ageValue; alert(params); // 3.4 配置ajax對象,並且取發送這條數據 xhr.open('get', 'http://localhost:3550/get?' + params); xhr.send(); xhr.onload = function() { console.log(xhr.responseText) } } </script>
- 伺服器端
// 6.3 對應03html文件 app.get('/get', (req, res) => { res.send(req.query); // req表示的就是我們的伺服器的響應,我們的query拿到的就是傳遞過來的值 // console.log(req.query); });
傳遞參數之——POST?如何傳遞
post的請求參數是放在請求體中
post必須明確的設置請求參數報文的類型,這個類型是固定的寫法
當然了我們呢還有另外的一種類型。這將會在後面慢慢的講到
在http傳輸的時候,發送的數據塊就是報文,報文的組成是報文體還有報文頭
( 參數名詞=參數值,多個參數用&分割 的形式傳遞的數據) ===application/x-www-form-urlencoded
<script type="text/javascript"> //需求點擊按鈕通過post發送給伺服器 //1.獲取元素對象 var btn = document.getElementById('btn'); var username = document.getElementById('username'); var age = document.getElementById('age'); // 2.綁定事件 btn.onclick = function() { //3.事件處理程式 // 創建ajax對象 var xhr = new XMLHttpRequest(); // 獲取用戶在文本框中輸入的值 var nameValue = username.value; var ageValue = age.value; // 拼接請求參數 var params = 'username=' + nameValue + '&age=' + ageValue; // 配置ajax對象 xhr.open('post', 'http://localhost:3000/post'); // 設置請求參數格式的類型(post請求必須要設置)。這個是必須要的固定格式 xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); //注意啊 這個不是調用 這個是直接丟進去 xhr.send(params); // 獲取伺服器端響應的數據 xhr.onload = function() { console.log(xhr.responseText) } } </script>
伺服器端
+++ // 6.4 對應04html文件 伺服器要用一個模組來接受POST請求 const bodyParser = require('body-parser'); // 6.4 對應04html文件 伺服器要用一個模組來接受POST請求,這些請求的資訊就存在了我們的req.body中 app.post('/post', (req, res) => { res.send(req.body); // console.log(req.body); }); +++
傳遞參數之——POST,JSON 發送POST 並且發送的是json
我們的post的時候我們可以發送
( JSONl類型的報文) ===application/JSON
1.html程式碼
- 我們需要設置另外的Content-type的類型。把json字元串傳遞給伺服器
- 注意啊我們傳遞的時候要把json對象轉換成jsom字元串再傳遞
<script type="text/javascript"> //我們的post要發送一些json字元串 // 1.創建ajax對象 var xhr = new XMLHttpRequest(); // 2.告訴Ajax對象要向哪發送請求,以什麼方式發送請求 // 1)請求方式 2)請求地址 xhr.open('post', 'http://localhost:3550/json'); // 通過請求頭告訴伺服器端客戶端向伺服器端傳遞的請求參數的格式是什麼 xhr.setRequestHeader('Content-Type', 'application/json'); // JSON.stringify() 將json對象轉換為json字元串 // 3.發送請求,我們要轉化為json字元串 xhr.send(JSON.stringify({ name: 'lisi', age: 50 })); // 4.獲取伺服器端響應到客戶端的數據 xhr.onload = function() { console.log(xhr.responseText) } </script>
2.伺服器程式碼
- 我們在伺服器要使用另外的方式去構造我們的伺服器解析請求方式
//6.5另外的解析方式 app.use(bodyParser.json()); +++ // 6.5 對應05html文件 app.post('/json', (req, res) => { res.send(req.body); console.log(req.body); }); +++
注意get提交不能夠提交json數據提交
補充:落後的伺服器響應數據的獲取
原理 ajax創建的時候,使用的時候每一個過程都有一個ajax狀態碼。它有五個,狀態 這哥時候我們就可以用這個來獲取伺服器數據
0.-狀態碼(未初始化還沒有調用open()
1.-請求建立(建立了鏈接但是沒有發就是沒有調用send()
2.-請求發生完畢
3.-請求在處理中。這個時候我們的部分數據就可以用了
4.完成,獲取到了伺服器的響應
如何獲取ajax的狀態碼?我們有一個redaStat方法,利用這個就可以弄好
我們還有一個事件
當ajax狀態碼發生變化的時候觸發。我們使用這個事件就可以捕獲各種狀態的狀態碼了
onreadyStarte
程式碼說明 xhr.readyState獲取狀態碼
xhr.open(‘get’, ‘http://localhost:3000/readystate‘);表示已經配置好了
xhr.onreadystatechange 當ajax狀態發生變化的時候觸發這個事件 2-3-4的狀態碼都在這裡可以捕獲 這個事件要放在send之前,
<script type="text/javascript"> var xhr = new XMLHttpRequest(); // 0 已經創建了ajax對象 但是還沒有對ajax對象進行配置 //一定要搞的,new一個對象 console.log(xhr.readyState); //狀態碼 0 xhr.open('get', 'http://localhost:3000/readystate'); // 1 已經對ajax對象進行配置 但是還沒有發送請求 console.log(xhr.readyState); //狀態碼 1 // 當ajax狀態碼發生變化的時候出發 xhr.onreadystatechange = function() { // 2 請求已經發送了 // 3 已經接收到伺服器端的部分數據了 // 4 伺服器端的響應數據已經接收完成 console.log(xhr.readyState); // 對ajax狀態碼進行判斷 如果狀態碼的值為4就代表數據已經接收完成了 //這個時候我們就可以獲取數據了 if (xhr.readyState == 4) { console.log(xhr.responseText); } } xhr.send();
伺服器端
// 6.7 對應07html文件 app.get('/error', (req, res) => { // console.log(abc); //這個是在伺服器端的方法,設置http狀態碼 res.status(400).send('not ok'); });
對比一下兩個獲取伺服器數據的方式的區別
ajax錯誤處理
怎麼會有錯誤呢?就是你給伺服器發了一個錯誤的東西,伺服器不能做出正確的響應於是乎給你反了一個非200的狀態碼,這個時候我們可以通過ajax捕獲到這個狀態碼,從而進行對應的提示
我們的ajax下面有一個 點status這個屬性報錯的就是http狀態碼
<body> <button id="btn">發送Ajax請求</button> </body> <script type="text/javascript"> // 我們的頁面錯誤總計一共有四種,我們根據不用的http錯誤狀態碼,進行處理 var btn = document.getElementById('btn'); btn.onclick = function() { // 1.創建ajax對象 var xhr = new XMLHttpRequest(); // 2.告訴Ajax對象要向哪發送請求,以什麼方式發送請求 // 1)請求方式 2)請求地址 xhr.open('get', 'http://localhost:3550/error'); // 3.發送請求 xhr.send(); // 4.獲取伺服器端響應到客戶端的數據 xhr.onload = function() { // xhr.status 獲取http狀態碼 console.log(xhr.responseText); if (xhr.status == 400) { alert('請求出錯') } } // 當網路中斷時會觸發onerrr事件.斷網的時候就會觸發 xhr.onerror = function() { alert('網路中斷, 無法發送Ajax請求') } } // Ajax狀態碼: 表示Ajax請求的過程狀態 ajax對象返回的 // Http狀態碼: 表示請求的處理結果 是伺服器端返回的 </script>
- 將來我們就可以使用各種狀態,來結合業務需求
// 6.7 對應07html文件 app.get('/error', (req, res) => { // console.log(abc); //這個是在伺服器端的方法,設置http狀態碼,伺服器端的狀態碼的可以手動更改 res.status(400).send('not ok'); });
- 接下里我們來看看這些狀態碼
400表示請求出錯了 伺服器給你返回了一個錯誤狀態碼
404 表示沒有在伺服器上找到。意思就是你沒有連上伺服器 這個時候你需要看一下是不是你的地址寫錯了
500 表示伺服器內部業務邏輯出錯了,通常這種事實你就要去跟後台開發人員進行回饋了
網路中斷,沒有網路,這個情況下我們的onlad是不會被觸發的,但是我們的oneerror可以觸發。這個時候你就可以用這個來做錯誤處理了
如何模擬斷網狀態?
這樣你就斷網了
xhr.onerror = function() { alert('網路中斷, 無法發送Ajax請求') }
區分一下http狀態碼還有ajax狀態碼
Ajax狀態碼: 表示Ajax請求的過程狀態 ajax對象返回的
Http狀態碼: 表示請求的處理結果 是伺服器端返回的
ajaxIE兼容性
要讀取文件 node下你必須引入另一個模組處理文件讀取
//6.8 讀取文件的模組 const fs = require('fs'); // 6.8 對應08html文件 app.get('/cache', (req, res) => { //讀取fs對象下的衣蛾讀取文件的犯法。讀取成功之後放回結果 通過伺服器我給他載入到res裡面去 fs.readFile('./test.txt', (err, result) => { res.send(result); }); });
在ie中 是比較垃圾 有快取問題,這個ie瀏覽器的問題不是我們的問題
我們的解決只需要 發生的請求每一次都隨機變化就行了
xhr.open(‘get’, ‘http://localhost:3000/cache?t=‘ + Math.random());
注意啊 如果你的t是伺服器要求的數據變數 那麼你就不能用t了!!一定要注意
<button id="btn">發送Ajax請求</button> <script type="text/javascript"> var btn = document.getElementById('btn'); btn.onclick = function() { // 1.創建ajax對象 var xhr = new XMLHttpRequest(); // 2.告訴Ajax對象要向哪發送請求,以什麼方式發送請求 // 1)請求方式 2)請求地址 // 3.發送請求 xhr.send(); // 4.獲取伺服器端響應到客戶端的數據 xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { alert(xhr.responseText); } } } </script>
ajax的非同步
非同步ajax的發生和處理的時候都是非同步的
我們只是寫了一個ajax就寫了怎麼多程式碼。我們要封裝 發生多次的時候就方便多了
程式碼比較複雜 你只需要會用就完事
/** * 描述 * * * * 使用說明:type表示請求方式有兩種get還有post url是地址 data{}裡面傳遞的你的請求數據 不管你是get還是post不管你是要傳遞json還是字元串你就給我嗎用就行了 sucesscs:是成功能的函數 error:是失敗之後的回調 關於返回值:放回值都在我們的回調函數裡面 的responseText身上。所有你回調函數一下 直接用responseText就能拿到響應回來的所有數據了 默認值 get 頭是application/x-www-form-urlencoded這種形式 注意:如果你需要狀態碼 你只需要在erro回調裡面獲取xhs.statsus還有xhs.onreddrSataius再做錯誤的業務處理就行 * * * @date 2020-04-04 * @param {url} 將要請求的地址 * @param {data{} } 請求傳遞出去的參數 * @param {sucesscs} 成功之後的回調 * @param {error } 失敗之後的回調 * @returns {any} */ /* 使用舉例 ajax({ url: 'http://localhost:3550/get',//必須 data: {//可選默認是空 username: username.value, age: age.value, }, header: { 'Content-Type': 'application/x-www-form-urlencoded' //可選默認是application/x-www-form-urlencoded }, success: function(data) { console.log(data); }, error: function(data) {} }) */ function ajax(options) { // 存儲的是默認值 var defaults = { type: 'get', url: '', data: {}, header: { 'Content-Type': 'application/x-www-form-urlencoded' //這個是默認的 }, success: function() {}, error: function() {} }; // 使用options對象中的屬性覆蓋defaults對象中的屬性,assign是一個覆蓋另一個對象的方法 Object.assign(defaults, options); //默認值 get 頭是application/x-www-form-urlencoded這種形式 // 創建ajax對象 var xhr = new XMLHttpRequest(); // 拼接請求參數的變數 var params = ''; //parmas是我們的請求過來的參數 // 循環用戶傳遞進來的對象格式參數 for (var attr in defaults.data) { // 將參數轉換為字元串格式 params += attr + '=' + defaults.data[attr] + '&'; } // 將參數最後面的&截取掉 // 將截取的結果重新賦值給params變數,拼接操作 params = params.substr(0, params.length - 1); // 判斷請求方式 if (defaults.type == 'get') { defaults.url = defaults.url + '?' + params; } // 配置ajax對象 xhr.open(defaults.type, defaults.url); // 如果請求方式為post if (defaults.type == 'post') { // 用戶希望的向伺服器端傳遞的請求參數的類型 var contentType = defaults.header['Content-Type'] // 設置請求參數格式的類型 xhr.setRequestHeader('Content-Type', contentType); // 判斷用戶希望的請求參數格式的類型 // 如果類型為json if (contentType == 'application/json') { // 向伺服器端傳遞json數據格式的參數 xhr.send(JSON.stringify(defaults.data)) } else { // 向伺服器端傳遞普通類型的請求參數 xhr.send(params); } } else { // 發送請求 xhr.send(); } // 監聽xhr對象下面的onload事件 // 當xhr對象接收完響應數據後觸發 xhr.onload = function() { // xhr.getResponseHeader() // 獲取響應頭中的數據 var contentType = xhr.getResponseHeader('Content-Type'); // 伺服器端返回的數據 var responseText = xhr.responseText; // 如果響應類型中包含applicaition/json,伺服器在響應的時候會在響應頭附上響應的數據類型 //includes就是堅持字元串是否包含某簡直 if (contentType.includes('application/json')) { // 將json字元串轉換為json對象 responseText = JSON.parse(responseText) } // 當http狀態碼等於200的時候 if (xhr.status == 200) { //在這裡我們也把xhr對象放回回去。讓我們的回調函數,有更多的控制權 // 請求成功 調用處理成功情況的函數 defaults.success(responseText, xhr); } else { // 請求失敗 調用處理失敗情況的函數 defaults.error(responseText, xhr); } } }