Lợi thế của Javascript (Js) thực sự nổi bật đó là việc tạo, cập nhật, thay đổi, sửa xoá dữ liệu cục bộ mà không phải load lại toàn bộ trang web. Nhưng để đạt được việc đó thì phải cần thời gian cho Javascript tiến hoá. Và hôm nay ta sẽ đi tìm hiểu quá trình này nhé.
Tóm Tắt
AJAX
Trong thời gian xa xưa xây dựng website thì công nghệ sử dụng dựa hoàn toàn vào HTML và mỗi thao tác từ người dùng thì đều phải tải lại trang từ trang chủ. Điều này làm trang web hoạt động kém hiệu quả và trải nghiệm không tốt đối với người dùng làm quá tải máy chủ, tăng băng thông truyền tải, lãng phí tài nguyên.
Vì thế cần phải có một công nghệ nào đó cải thiện việc này. Và AJAX đã ra đời để bù đắp những nhược điểm của web truyền thống.
Cái tên Ajax đã được cha đẻ của nó là ông Jesse James Garrett đưa ra và sử dụng lần đầu vào năm 2005.
Cùng tìm hiểu sâu hơn vào công nghệ này thì
AJAX nghĩa là Asynchronous Javascript And XML
nó không phải là ngôn ngữ lập trình mà là kết hợp các công nghệ với nhau và điểm khác biệt cơ bản với cách truyền thống là với công nghệ này thì nó xử lý thông tin trên máy khách (client) thay vì máy chủ (server) vừa giúp giảm tải cho server lại vừa tăng trải nghiệm của người dùng.
Cụ thể thì nhờ vào việc hoạt động bất đồng bộ asynchronous
để xử lý nhiều yêu cầu cùng một lúc dựa vào Javascript, HTML DOM (để hiển thị hoặc sử dụng dữ liệu) và dùng XML
để chứa dữ liệu trong quá trình trao đổi nhận và gửi dữ liệu từ trình duyệt web tới máy chủ.
Cụ thể hơn thì ta có hình minh hoạ bên dưới
So sánh web truyền thống và ajax
Qua hình ta có thể thấy khác biệt rõ ràng là với cách truyền thống thì với mỗi request từ trình duyệt (client) thì máy chủ phải gửi cả html, css, data cho trình duyệt tải lại trang và hiển thị cho người dùng.
Còn với AJAX thì hai bên trình duyệt vào máy chủ chỉ trao đổi XML data
còn lại việc hiển thị lại html, css thì do AJAX đảm nhiệm và hiển nhiên việc này giảm tải cho máy chủ và tiết kiệm băng thông đồng thời tăng trải nghiệm cho người dùng giúp họ thấy việc tương tác với trang web nhanh hơn…
Cũng chính vì sự tiện lợi của AJAX mà chúng ta đã có những React, Angular và Vue 😆
Bây giờ ta đi sâu hơn vào cách hoạt động của AJAX và sau đó sẽ tìm hiểu ví dụ qua code cụ thể sau.
Mô tả cụ thể hơn cách AJAX hoạt động
Cụ thể hơn cách AJAX hoạt động
- Một sự kiện xảy ra ở trang web (trang được load, một button được click)
- Một XMLHttpRequest object được tạo bởi Javascript
- XMLHttpRequest object gửi một request đến web server
- Server xử lý request đó
- Server gửi response về cho trang web
- Response được đọc bởi Javascript
- Thực hiện một số hành động trên trang web bằng Javascript (ví dụ như cập nhật lại trang)
Giải thích từ ngữ
XMLHttPRequest
XMLHttpRequest (XHR) là một hàm khởi tạo có sẵn của trình duyệt dùng để giao tiếp với server. XHR cũng là một Web APIs nên nó chỉ có trên môi trường trình duyệt, không có ở Nodejs
Tạo một XMLHttpRequest với cú pháp
1
var
xhttp
=
new
XMLHttpRequest
()
Một số phương thức của XMLHttpRequest như sau
Phương thức
Mô tả
new XMLHttpRequest()
Tạo mới XMLHttpRequest object
abort()
Hủy request hiện tại
getAllResponseHeaders()
Returns tất cả thông tin header
getResponseHeader()
Returns thông tin header chỉ định
open(method, url, async, user, psw)
Quy định request
method: Loại request (GET, POST, PUT, DELETE)
url: đường dẫn đến server; async: true (bất đồng bộ) hoặc false (đồng bộ)
user: tùy chọn username
psw: tùy chọn password
send(body)
Gửi body data đến server. body có thể là; Document, cần serialized trước khi gửi; Blob, BufferSource, FormData, URLSearchParams, or USVString object.null; Nếu không có giá trị nào cho body thì mặc định null được sử dụng.
setRequestHeader()
Thêm các giá trị vào trong header request
Một số thuộc tính của XMLHttpRequest
Thuộc tính
Mô tả
onreadystatechange
Xác định một function được gọi khi thuộc tính readyState thay đổi
readyState
Mô tả trạng thái của XMLHttpRequest.
0: request chưa được khởi tạo.
1: kết nối với server được thiết lập.
2: request được server tiếp nhận.
3: đang xử lý request.
4: request kết thúc và response đã sẵn sàng để dùng
responseText
Return về response như một string
responseXML
Return về response như một XML
status
Return về status của request.
200: “OK”.
403: “Forbidden”.
404: “Not Found”.
Xem danh sách đầy đủ tại Http Messages Reference
statusText
Return về status dạng text (Ví dụ “OK” hoặc “Not Found”)
Ví dụ XMLHttpRequest
GET
Cùng xem ví dụ dùng XHR để GET
request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function
loadDoc
(){
var
xhttp
=
new
XMLHttpRequest
()
// function này sẽ chạy mỗi khi readyState thay đổi
xhttp
.
onreadystatechange
=
function
()
{
// khi request thành công
if
(
this
.
readyState
==
4
&&
this
.
status
==
200
)
{
document
.
getElementById
(
'demo'
).
innerHTML
=
this
.
responseText
console
.
log
(
'XMLHttpRequest GET'
,
this
.
responseText
)
}
xhttp
.
open
(
'GET'
,
'https://httpbin.org/get'
,
true
)
xhttp
.
send
()
}
loadDoc
()
}
Kết quả trả về là
{ "args": {}, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-US,en;q=0.9,vi;q=0.8", "Host": "httpbin.org", "Origin": "https://cdpn.io", "Referer": "https://cdpn.io/", "Sec-Ch-Ua": "\"Google Chrome\";v=\"89\", \"Chromium\";v=\"89\", \";Not A Brand\";v=\"99\"", "Sec-Ch-Ua-Mobile": "?0", "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "cross-site", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36", "X-Amzn-Trace-Id": "Root=1-60ab2c7e-3c7440b55b69b1dd1eebd0a1" }, "origin": "113.161.70.139", "url": "https://httpbin.org/get" }
POST
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function
send
()
{
var
xhttp
=
new
XMLHttpRequest
()
// function này sẽ chạy mỗi khi readyState thay đổi
xhttp
.
onreadystatechange
=
function
()
{
// Khi request thành công
if
(
this
.
readyState
==
4
&&
this
.
status
==
200
)
{
document
.
getElementById
(
'demo'
).
innerHTML
=
this
.
responseText
}
}
xhttp
.
open
(
'POST'
,
'https://httpbin.org/post'
,
true
)
const
body
=
{
name
:
'doidev'
,
skill
:
'chém gió'
,
point
:
100
}
xhttp
.
send
(
JSON
.
stringify
(
body
))
}
send
()
Kết quả trả về là
{ "args": {}, "data": "{\"name\":\"doidev\",\"skill\":\"ch\u00e9m gi\u00f3\",\"point\":100}", "files": {}, "form": {}, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-US,en;q=0.9,vi;q=0.8", "Content-Length": "50", "Content-Type": "text/plain;charset=UTF-8", "Host": "httpbin.org", "Origin": "https://cdpn.io", "Referer": "https://cdpn.io/", "Sec-Ch-Ua": "\"Google Chrome\";v=\"89\", \"Chromium\";v=\"89\", \";Not A Brand\";v=\"99\"", "Sec-Ch-Ua-Mobile": "?0", "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "cross-site", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36", "X-Amzn-Trace-Id": "Root=1-60ab2e24-3340d7973486ab194e6206bf" }, "json": { "name": "doidev", "point": 100, "skill": "ch\u00e9m gi\u00f3" }, "origin": "113.161.70.139", "url": "https://httpbin.org/post" }
Cách dùng AJAX
Dùng XMLHttpRequest
Đây là cách dùng cổ xưa
nhất và rườm rà nhất
Dùng Jquery
Cách dùng qua thư viện jQuery cung cấp cho ta nhiều phương thức tiện lợi như load
, ajax
, get
, getJSON
Dùng FetchApi
Fetch API là một cách mà trình duyệt cung cấp, nó nằm mặc định trong trình duyệt và ta chỉ việc sử dụng với nhiều tính năng nâng cao và dễ sử dụng hơn XMLHttpRequest
Dùng axios
Axios, phổ biến nhất, nó là một thư viện chuyên dụng cho việc xử lý AJAX cũng như gọi API. Cung cấp hàng tá tính năng hay, dùng được cho cả môi trường trình duyệt và Node (nếu trình duyệt nó sẽ dựa trên XHR, nếu là Node thì là HTTP interface)
FETCH API
Fetch là một API đơn giản cung cấp cho chúng ta khả năng gửi và nhận request thông qua trình duyệt. Nếu như XMLHttpRequest
dùng callback thì Fetch API dùng Promise
vì thế sẽ tiện lợi hơn khi thao tác và xử lý.
Với Fetch API thì dữ liệu dùng ở đây là dạng JSON
và ta cùng đi tìm hiểu về nó một chút.
JSON
JSON (JavaScript Object Notation) là một chuỗi text được viết dưới dạng Javascript Object dùng để lưu trữ và trao đổi dữ liệu.
JSON thường được dùng để lưu trữ string, number, boolean, array, object, null.
Định dạng JSON có thể dễ dàng sử dụng ở các ngôn ngữ lập trình khác nhau. Ở Javascript bạn có thể thao tác với JSON thông qua JSON.parse()
và JSON.stringify()
Cú pháp JSON
- Dữ liệu là cặp name:value, name bọc trong dấu nháy kép
" "
- Các cặp dữ liệu được ngăn cách bởi dấu phẩy
- Ngoặc nhọn mô tả object
- Ngoặc vuông mô tả mảng
Loại dữ liệu
Trong JSON thì dữ liệu phải là một trong những loại
- string
- number
- object
- array
- boolean
- null
Chuyển Object thành JSON
1
2
3
4
5
6
7
const
siteObject
=
{
title
:
'doidev'
,
description
:
'chuyên chém gió'
,
size
:
'1000TB'
}
const
siteJSON
=
JSON
.
stringify
(
siteObject
)
console
.
log
(
siteJSON
)
Chuyển JSON thành Object
1
2
3
const
siteJSON
=
`{"title":"doidev","description":"chuyên chém gió","size":"1000TB"}`
const
siteObject
=
JSON
.
parse
(
siteJSON
)
console
.
log
(
siteObject
)
Sử dụng Fetch API
Setup
Một setup request được thiết lập đơn giản
1
2
3
fetch
(
'https://example.com/file.json'
)
.
then
((
response
)
=>
response
.
json
())
.
then
((
data
)
=>
console
.
log
(
data
))
Lưu ý là
Promise
return từfetch()
sẽ không reject dựa trên HTTP error status ngay cả khi HTTP 404 hoặc 500. Thay vì đó, nó sẽ resolve bình thường (vớiok
status làfalse
) và nó chỉ sẻ reject khi mà mạng lỗi hoặc bất cứ điều gì ngăn cản request hoàn thành.
1
2
3
4
5
6
7
8
9
10
fetch
(
'https://example.com/file.json'
)
.
then
(
function
(
response
)
{
if
(
!
response
.
ok
)
{
throw
Error
(
response
.
statusText
)
}
// code cho phần trả về kết quả
})
.
catch
(
function
(
error
)
{
console
.
log
(
'Error nhé: \n'
,
error
)
})
Đọc một response
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
fetch
(
'https://example.com/file.json'
)
.
then
(
function
(
response
)
{
if
(
!
response
.
ok
)
{
throw
Error
(
response
.
statusText
)
}
// read the response as json
return
respons
.
json
()
})
.
then
(
function
(
responseAsJson
)
{
// do logic with JSON
console
.
log
(
responseAsJson
)
})
.
catch
(
function
(
error
)
{
console
.
log
(
'Error nè: \n'
,
error
)
})
Mặc định nếu không truyền tham số thứ 2 thì fetch sẽ dùng phương thức GET
, còn muốn chỉ rõ phương thức như POST
, PUT
… thì phải truyền tham số thứ 2 vào. Ví dụ POST
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
async
function
postData
(
url
=
''
,
data
=
{})
{
const
response
=
await
fetch
(
url
,
{
method
:
'POST'
,
//GET, POST, PUT, DELETE, etc.
mode
:
'cors'
,
// no-cors, *cors, same-origin
cache
:
'no-cache'
,
// *default, no-cache, reload, force-cache,only-if-cached
credentials
:
'same-origin'
,
// include, *same-origin, omit
headers
:
{
'Content-Type'
:
'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded'
},
redirect
:
'follow'
,
// manual, *follow, error
referencePolicy
:
'no-referrer'
,
// no-referrer, * no-referrer-when-downgrade, origin, origin-when-cross-origin,same-origin, strict-origin, strict-origin-when-cross-origin,unsafe-url
body
:
JSON
.
stringify
(
data
)
// body data type must match "Content-Type" header
})
return
response
.
json
()
// parses JSON response into native Javascript ojbject
}
postData
(
'https://example.com/file'
,{
file
:
33
})
.
then
((
data
)
=>
{
console
.
log
(
data
)
// JSON data parsed by 'data.json()' call
})
Bài này chém cơ bản về AJAX và fetch API, hi vọng qua đó thì ta có một cái hiểu sơ bộ và từ từ tiếp tục tìm hiểu sâu hơn