AJAX – 網路請求
什麼是 AJAX? 它如何改善網頁使用體驗?
// AJAX
// Asynchronous JavaScript and XML
// 非同步的 JavaScript 與 XML 技術
什麼是網路請求?
// 網路請求
/*
透過 Chrome 執行 Enter URL 動作,
我傳送了一個網路請求,
取得: get URL 網頁上的資訊
*/
// 其他軟體也可以發出網路請求
// 透過 JS 發出網路請求
從網頁架構瞭解網頁請求 – 上集
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Review JS</title>
</head>
<body>
<h1>複習 Review JS</h1>
<ul class="list"></ul>
<img src="img.jpg" alt="">
<script src="all.js"></script>
</body>
</html>
// 開啟 Network 方法,查出有幾個網路請求
// 方法一
// Chrome 瀏覽器 > 滑鼠右鍵檢查 > Network
// 方法二
// 自訂及管理 Google Chrome > 更多工具 > 開發人員工具 > Network
從網頁架構瞭解網頁請求 – 下集
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Review JS</title>
</head>
<body>
<h1>複習 Review JS</h1>
<ul class="list"></ul>
<img src="image.jpg" alt="">
<script src="all.js"></script>
</body>
</html>
// 從網頁架構瞭解網頁請求 - 下集
// Chrome 瀏覽器輸入網址按下 Enter 後,就會發送 get 請求到伺服器上
// 再經由伺服器回傳資料給 Chrome 瀏覽器
// 1. index.html
// 2. img
// 3. all.js
// 瀏覽器解析到圖片時,會去跟本地端伺服器請求圖片檔案
// 網路請求有先後順序,並不是一次全部請求
網頁請求狀態碼
// HTTP 狀態碼
// 網頁請求狀態碼
// HTTP 狀態碼
// 1. 資訊回應 (Informational responses, 100 - 199)
// 2. 成功回應 (Successful responses, 200 - 299)
// 3. 重定向 (Redirects, 300 - 399)
// 4. 用戶端錯誤 (Client errors, 400 - 499)
// 5. 伺服器端錯誤 (Server errors, 500 - 599)
// 常見的網頁請求狀態碼
// 404 Not Found - 伺服器找不到請求的資源
// 200 OK - 請求成功
// 304 Not Modified - 無需再次傳輸請求的內容
// 500 Internal Server Error - 伺服器端發生未知或無法處理的錯誤
// 清除快取並強制重新載入 (開發人員工具要打開)
// 方法一
// 重新整理圖示長按左鍵後選取清除快取並強制重新載入
// 方法二
// 重新整理圖示右鍵後選取清除快取並強制重新載入
request、response 講解
// request、response 講解
// request(請求): 傳送給伺服器要什麼資料
// 瀏覽器 → request(請求) → 伺服器
// response(回傳): 回傳給瀏覽器資料
// 瀏覽器 ← response(回傳) ← 伺服器
// response header (Headers > Response Headers)
// response data (Response)
// Chrome > Network > Name - index.html > Headers > Request Headers
用 Node.js 開啟伺服器,更加瞭解 request、response 的差異
// Chrome → request → Node.js 後端伺服器
// Chrome ← response ← Node.js 後端伺服器
// 使用終端機用 Node.js 開啟伺服器
// node app.js
// app.js - 1
const http = require("http");
http.createServer(function(request, response) {
console.log(request);
if (request.url == "/") {
console.log("接收到網頁請求!");
response.writeHead(200, { "Content-Type": "text/HTML" });
response.write("<h1>index</h1>");
response.end();
}
}).listen(process.env.PORT || 3000);
console.log("Server已開啟port: 3000.");
// app.js - 2
const http = require("http");
http.createServer(function(request, response) {
console.log(request.url);
if (request.url == "/") {
console.log("接收到網頁請求!");
response.writeHead(200, { "Content-Type": "text/HTML" });
response.write("<h1>index</h1>");
response.end();
} else {
console.log("接收到網頁請求!");
response.writeHead(200, { "Content-Type": "text/HTML" });
response.write("<h1>not index</h1>");
response.end();
}
}).listen(process.env.PORT || 3000);
console.log("Server已開啟port: 3000.");
AJAX – axios 套件教學
各種發出網路請求的 JS 寫法種類介紹
// JavaScript 原生寫法
// 1. XMLHttpRequest
// 2. Fetch
// 套件,無須額外載入 JS
// axios
// 使用 XMLHttpRequest
function reqListener() {
console.log(this.responseText);
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "http://www.example.org/example.txt");
oReq.send();
// Using the Fetch API
fetch("http://example.com/movies.json")
.then(function (response) {
return response.json();
})
.then(function (myJson) {
console.log(myJson);
});
axios 環境安裝
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Review JS</title>
</head>
<body>
<h1>複習 Review JS</h1>
<script src="https://cdn.jsdelivr.net/npm/axios@1.1.2/dist/axios.min.js"></script>
<script src="all.js"></script>
</body>
</html>
// all.js
// 套件 CDN 程式碼與自己撰寫載入的程式碼載入順序有差
// 套件程式碼載入放在自己撰寫的程式碼之前
// 檢查套件載入有沒有成功
// 方法一
// 使用 Chrome Network 查看 Status Code
// 方法二
// 使用 Console 查看
console.log(axios);
axios – 嘗試串接外部資料
// all.js
// https://hexschool.github.io/ajaxHomework/data.json
axios.get('https://hexschool.github.io/ajaxHomework/data.json')
.then(function (response) {
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
});
axios – response 參數詳細講解
// all.js
// When using then, you will receive the response as follows:
axios.get('https://hexschool.github.io/ajaxHomework/data.json')
.then(function (response) {
// response 為物件格式
console.log(response);
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
});
axios – 將外部資料寫入到網頁上
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Review JS</title>
</head>
<body>
<h1>複習 Review JS</h1>
<h2 class="title"></h2>
<script src="https://cdn.jsdelivr.net/npm/axios@1.1.2/dist/axios.min.js"></script>
<script src="all.js"></script>
</body>
</html>
// all.js
axios.get('https://hexschool.github.io/ajaxHomework/data.json')
.then(function (response) {
let ary = response.data;
console.log(ary[0].name);
const title = document.querySelector(".title");
title.textContent = ary[0].name;
});
axios – 非同步觀念
// all.js
let ary = [];
// 非同步 AJAX 觀念
// 透過 AJAX 方法發送 get 請求,當資料還沒回傳時,程式碼還是會繼續往下執行
axios.get('https://hexschool.github.io/ajaxHomework/data.json')
.then(function (response) {
console.log("資料有回傳了"); // 1. 資料有回傳了
ary = response.data;
console.log(ary); // 2. [{...}]
});
console.log(ary); // 3. []
// 執行順序
// 3 > 1 > 2
透過函式設計處理非同步
// all.js
let ary = [];
axios.get('https://hexschool.github.io/ajaxHomework/data.json')
.then(function (response) {
console.log("資料有回傳了"); // 1. 資料有回傳了
ary = response.data;
renderData();
});
// 資料渲染
// 資料回傳後,再執行函式
function renderData() {
console.log(ary); // 2. [{...}]
const title = document.querySelector(".title");
title.textContent = ary[0].name;
}
console.log(ary); // 3. []
// 執行順序
// 3 > 1 > 2
AJAX POST API 講解
網路請求種類介紹
post 網路請求文件介紹
// readme.md
// 六角學院 AJAX 練習
// 注意,此範例僅供練習,並不會儲存用戶資料置資料庫(僅緩存)。
// 註冊
// 新增一個帳號。
// Method: POST
// URL: https://hex-escape-room.herokuapp.com/api/user/signup
// Data:
// {
// email: 'lovef2e@hexschool.com',
// password: '12345678'
// }
// Success Response:
// {
// "success": true,
// "result": {},
// "message": "帳號註冊成功"
// }
// Error Response:
// {
// "success": false,
// "result": {},
// "message": "此帳號已被使用"
// }
// 登入
// 登入一個已存在的帳號。
// Method: POST
// URL: https://hex-escape-room.herokuapp.com/api/user/signin
// Data:
// {
// email: 'lovef2e@hexschool.com',
// password: '12345678'
// }
// Success Response:
// {
// "success": true,
// "result": {},
// "message": "登入成功"
// }
// Error Response:
// {
// "success": false,
// "result": {},
// "message": "此帳號不存在或帳號密碼錯誤"
// }
四種常見的 POST 請求 content-type 介紹
// all.js
// 常見請求資料格式 request header Content-Type
// 1. application/x-www-form-urlencoded
// 2. application/json
// 3. multipart/form-data
// 4. text/plain (記事本格式最少使用)
// axios 預設屬於第2種請求資料格式,支援其他格式,可以自己設定
// multipart/form-data: 傳送檔案格式的時候,檔案: 圖片、pdf、word、mp4
// application/x-www-form-urlencoded: 是屬於 <form> 表單的原生提交方式
透過 axios 實驗註冊 post 網路請求
// axios post 範例
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Review JS</title>
</head>
<body>
<h1>複習 Review JS</h1>
<script src="https://cdn.jsdelivr.net/npm/axios@1.1.2/dist/axios.min.js"></script>
<script src="all.js"></script>
</body>
</html>
// all.js - 第二個參數是資料的物件格式 - 方式一
// url
// https://hex-escape-room.herokuapp.com/api/user/signup
axios.post('https://hex-escape-room.herokuapp.com/api/user/signup', {
email: 'geehsu@hexschool.com',
password: '12345678'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// all.js - 第二個參數是資料的物件格式 - 方式二
// url
// https://hex-escape-room.herokuapp.com/api/user/signup
let obj = {
email: 'geehsu@hexschool.com',
password: '12345678'
};
axios.post('https://hex-escape-room.herokuapp.com/api/user/signup', obj)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
從 chrome 觀察 post 請求
// all.js
// 講解關於 Chrome 瀏覽器的底層運作
/*
透過瀏覽器開發人員工具除錯
Chrome Network > signup > Header, Payload, Response
Chrome Console
*/
// url
// https://hex-escape-room.herokuapp.com/api/user/signup
function callSignUp() {
let obj = {
email: "geehsu@hexschool.com",
password: "12345678",
};
axios
.post("https://hex-escape-room.herokuapp.com/api/user/signup", obj)
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
}
實作 axios DOM 表單註冊流程
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Review JS</title>
</head>
<body>
<h1>複習 Review JS</h1>
<label for="">帳號:</label>
<input type="text" class="account" />
<br />
<label for="">密碼:</label>
<input type="text" class="password" />
<br /><br />
<input type="button" value="送出" class="send" />
<script src="https://cdn.jsdelivr.net/npm/axios@1.1.2/dist/axios.min.js"></script>
<script src="all.js"></script>
</body>
</html>
// all.js
// url
// https://hex-escape-room.herokuapp.com/api/user/signup
const account = document.querySelector(".account");
const password = document.querySelector(".password");
const send = document.querySelector(".send");
// console.log(account, password, send);
send.addEventListener("click", function (e) {
// console.log("是否被點擊");
callSignUp();
});
function callSignUp() {
if (account.value == "" || password.value == "") {
alert("請填寫正確資訊");
return;
}
let obj = {};
obj.email = account.value;
obj.password = password.value;
// console.log(obj);
axios
.post("https://hex-escape-room.herokuapp.com/api/user/signup", obj)
.then(function (response) {
// console.log(response.data);
// alert(response.data.message);
if (response.data.message == "帳號註冊成功") {
alert("恭喜帳號註冊成功");
} else {
alert("帳號註冊失敗,有可能有人用你的email註冊!");
}
account.value = "";
password.value = "";
})
.catch(function (error) {
console.log(error);
});
}
AJAX POST 小節作業
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Review JS</title>
</head>
<body>
<h1>複習 Review JS</h1>
<h2>註冊功能</h2>
<label for="">帳號:</label>
<input type="text" class="signupAccount" />
<br />
<label for="">密碼:</label>
<input type="text" class="signupPassword" />
<br /><br />
<input type="button" value="送出" class="signupSend" />
<h2>登入功能</h2>
<label for="">帳號:</label>
<input type="text" class="loginAccount" />
<br />
<label for="">密碼:</label>
<input type="text" class="loginPassword" />
<br /><br />
<input type="button" value="送出" class="loginSend" />
<script src="https://cdn.jsdelivr.net/npm/axios@1.1.2/dist/axios.min.js"></script>
<script src="all.js"></script>
</body>
</html>
// all.js
// url
// signup
// https://hex-escape-room.herokuapp.com/api/user/signup
// signin / login
// https://hex-escape-room.herokuapp.com/api/user/signin
// 1.註冊功能
// 2.登入功能
// 宣告變數綁定 DOM 元素
const signupAccount = document.querySelector(".signupAccount");
const signupPassword = document.querySelector(".signupPassword");
const signupSend = document.querySelector(".signupSend");
// 事件監聽 click 按鈕
signupSend.addEventListener("click", function (e) {
console.log("觸發點擊事件!");
// 執行函式
callSignup();
});
// 宣告函式執行註冊功能
function callSignup() {
console.log("執行註冊功能");
if (signupAccount.value == "" || signupPassword.value == "") {
alert("請填寫正確內容");
// 回傳然後結束
return;
}
let obj = {};
obj.email = signupAccount.value;
obj.password = signupPassword.value;
console.log(obj);
// axios 套件 post 方法
axios
.post("https://hex-escape-room.herokuapp.com/api/user/signup", obj)
.then(function (response) {
console.log(response);
console.log(response.data);
console.log(response.data.message);
// 流程判斷
if (response.data.message == "帳號註冊成功") {
console.log("已成功註冊帳號!");
alert("已經成功註冊帳號!");
} else {
console.log("已有人註冊此email");
alert("已有人註冊此email");
}
signupAccount.value = "";
signupPassword.value = "";
})
.catch(function (error) {
console.log(error);
});
}
const loginAccount = document.querySelector(".loginAccount");
const loginPassword = document.querySelector(".loginPassword");
const loginSend = document.querySelector(".loginSend");
loginSend.addEventListener("click", function (e) {
console.log("觸發點擊事件");
callLogin();
});
function callLogin() {
console.log("執行登入功能");
if (loginAccount.value == "" || loginPassword.value == "") {
alert("請填寫正確內容");
return;
}
let obj = {};
obj.email = loginAccount.value;
obj.password = loginPassword.value;
console.log(obj);
axios
.post("https://hex-escape-room.herokuapp.com/api/user/signin", obj)
.then(function (response) {
console.log(response);
console.log(response.data.message);
if (response.data.message == "登入成功") {
alert("登入成功");
} else if (response.data.message == "此帳號不存在或帳號密碼錯誤") {
alert("此帳號不存在或帳號密碼錯誤");
}
loginAccount.value = "";
loginPassword.value = "";
})
.catch(function (error) {
console.log(error);
});
}