Tìm hiểu cách sử dụng API Bộ nhớ đệm để đặt dữ liệu ứng dụng của bạn ở chế độ có thể sử dụng khi không có mạng.
API Bộ nhớ đệm là một hệ thống lưu trữ và truy xuất mạng các yêu cầu và phản hồi tương ứng của chúng. Đây có thể là các yêu cầu thông thường và phản hồi được tạo trong quá trình chạy ứng dụng, hoặc chúng có thể chỉ được tạo nhằm mục đích lưu trữ dữ liệu để sử dụng sau này.
Cache API được tạo để cho phép trình chạy dịch vụ lưu các yêu cầu mạng vào bộ nhớ đệm để chúng có thể cung cấp phản hồi nhanh, bất kể tốc độ mạng hay tình trạng còn hàng. Tuy nhiên, bạn cũng có thể sử dụng API này làm cơ chế lưu trữ chung.
YouTube TV có ở đâu?
API Bộ nhớ đệm có trong tất cả trình duyệt hiện đại. Đó là
được hiển thị thông qua tài sản caches
toàn cầu, nên bạn có thể kiểm tra sự hiện diện của
API bằng cách phát hiện tính năng đơn giản:
const cacheAvailable = 'caches' in self;
Bạn có thể truy cập API Bộ nhớ đệm qua một cửa sổ, iframe, trình thực thi hoặc trình chạy dịch vụ.
Những thông tin có thể lưu trữ
Bộ nhớ đệm chỉ lưu trữ các cặp Request
và
Response
đại diện cho các yêu cầu và phản hồi HTTP,
. Tuy nhiên, yêu cầu và phản hồi có thể chứa bất kỳ loại dữ liệu nào
có thể truyền qua HTTP.
Có thể lưu trữ bao nhiêu tiền?
Tóm lại là rất nhiều, ít nhất là vài trăm megabyte và có khả năng hàng trăm gigabyte trở lên. Triển khai trình duyệt sẽ khác nhau, nhưng số lượng bộ nhớ có sẵn thường dựa trên dung lượng bộ nhớ có sẵn trên thiết bị.
Tạo và mở bộ nhớ đệm
Để mở bộ nhớ đệm, hãy sử dụng phương thức caches.open(name)
, truyền tên của
lưu vào bộ nhớ đệm dưới dạng tham số duy nhất. Nếu bộ nhớ đệm đã đặt tên không tồn tại,
đã tạo. Phương thức này trả về một Promise
phân giải bằng đối tượng Cache
.
const cache = await caches.open('my-cache');
// do something with cache...
Đang thêm vào bộ nhớ đệm
Có 3 cách để thêm một mục vào bộ nhớ đệm – add
, addAll
và put
.
Cả 3 phương thức đều trả về Promise
.
cache.add
Đầu tiên là cache.add()
. Hàm này sẽ nhận một tham số, hoặc là Request
hoặc URL (string
). Phương thức này gửi yêu cầu đến mạng và lưu trữ phản hồi
trong bộ nhớ đệm. Nếu
không tìm nạp được hoặc nếu mã trạng thái của phản hồi không nằm trong phạm vi 200,
thì sẽ không có nội dung nào được lưu trữ và Promise
sẽ từ chối. Xin lưu ý rằng nhiều nguồn gốc
Không thể lưu trữ các yêu cầu không ở chế độ CORS do các yêu cầu này trả về status
0
Những yêu cầu như vậy chỉ có thể được lưu trữ bằng put
.
// Retreive data.json from the server and store the response.
cache.add(new Request('/data.json'));
// Retreive data.json from the server and store the response.
cache.add('/data.json');
cache.addAll
Tiếp theo là cache.addAll()
. Hàm này hoạt động tương tự như add()
, nhưng sẽ mất một
mảng gồm các đối tượng Request
hoặc URL (string
). Cách này hoạt động tương tự như
gọi cache.add
cho từng yêu cầu riêng lẻ, ngoại trừ việc Promise
từ chối nếu có bất kỳ yêu cầu nào không được lưu vào bộ nhớ đệm.
const urls = ['/weather/today.json', '/weather/tomorrow.json'];
cache.addAll(urls);
Trong mỗi trường hợp, mục nhập mới sẽ ghi đè bất kỳ mục nhập hiện có nào trùng khớp. Việc này sử dụng cùng các quy tắc so khớp được mô tả trong phần về truy xuất.
cache.put
Cuối cùng, có cache.put()
cho phép bạn lưu trữ phản hồi
từ mạng hoặc tạo và lưu trữ Response
của riêng bạn. Phải mất hai
tham số. Đầu tiên có thể là đối tượng Request
hoặc URL (string
).
Thứ hai phải là Response
, từ mạng hoặc được tạo bởi
.
// Retrieve data.json from the server and store the response.
cache.put('/data.json');
// Create a new entry for test.json and store the newly created response.
cache.put('/test.json', new Response('{"foo": "bar"}'));
// Retrieve data.json from the 3rd party site and store the response.
cache.put('https://example.com/data.json');
Phương thức put()
có nhiều quyền hơn so với add()
hoặc addAll()
và
sẽ cho phép bạn lưu trữ phản hồi không phải CORS hoặc các phản hồi khác có trạng thái
mã của phản hồi không nằm trong phạm vi 200. Bản sao này sẽ ghi đè mọi thuộc tính trước đó
phản hồi cho cùng một yêu cầu.
Tạo đối tượng Yêu cầu
Tạo đối tượng Request
bằng URL cho đối tượng đang được lưu trữ:
const request = new Request('/my-data-store/item-id');
Làm việc với các đối tượng Phản hồi
Hàm khởi tạo đối tượng Response
chấp nhận nhiều loại dữ liệu, trong đó có
Các đối tượng Blob
, ArrayBuffer
, FormData
và chuỗi.
const imageBlob = new Blob([data], {type: 'image/jpeg'});
const imageResponse = new Response(imageBlob);
const stringResponse = new Response('Hello world');
Bạn có thể đặt loại MIME của Response
bằng cách đặt tiêu đề phù hợp.
const options = {
headers: {
'Content-Type': 'application/json'
}
}
const jsonResponse = new Response('{}', options);
Nếu bạn đã truy xuất Response
và muốn truy cập nội dung của nó, có
một số phương pháp trợ giúp mà bạn có thể sử dụng. Mỗi kết quả trả về một Promise
phân giải
có giá trị thuộc một loại khác.
Phương thức | Mô tả |
---|---|
arrayBuffer |
Trả về ArrayBuffer chứa nội dung, được chuyển đổi tuần tự thành
byte.
|
blob |
Trả về Blob . Nếu Response đã được tạo
với Blob thì Blob mới này sẽ có cùng
loại. Nếu không, Content-Type của
Response sẽ được dùng.
|
text |
Diễn giải các byte của phần nội dung dưới dạng chuỗi mã hoá UTF-8. |
json |
Diễn giải các byte của phần nội dung dưới dạng chuỗi được mã hoá UTF-8, sau đó thử
để phân tích cú pháp tệp dưới dạng JSON. Trả về đối tượng kết quả hoặc gửi một
Là giá trị TypeError nếu chuỗi không thể được phân tích cú pháp dưới dạng JSON.
|
formData |
Diễn giải các byte của phần nội dung dưới dạng dạng HTML, được mã hoá là
multipart/form-data hoặc
application/x-www-form-urlencoded Trả về a
FormData
hoặc gửi TypeError nếu không thể phân tích cú pháp dữ liệu.
|
body |
Trả về ReadableStream cho dữ liệu cơ thể. |
Ví dụ
const response = new Response('Hello world');
const buffer = await response.arrayBuffer();
console.log(new Uint8Array(buffer));
// Uint8Array(11) [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
Truy xuất từ bộ nhớ đệm
Để tìm một mục trong bộ nhớ đệm, bạn có thể sử dụng phương thức match
.
const response = await cache.match(request);
console.log(request, response);
Nếu request
là một chuỗi, trình duyệt sẽ chuyển đổi chuỗi đó thành Request
bằng cách gọi
new Request(request)
. Hàm trả về Promise
phân giải thành
Response
nếu tìm thấy mục nhập khớp hoặc undefined
nếu không tìm thấy.
Để xác định xem 2 Requests
có khớp hay không, trình duyệt sẽ sử dụng nhiều hơn là chỉ URL. Hai
các yêu cầu được coi là khác nhau nếu chúng có các chuỗi truy vấn khác nhau,
tiêu đề Vary
hoặc phương thức HTTP (GET
, POST
, PUT
, v.v.).
Bạn có thể bỏ qua một số hoặc tất cả những điều này bằng cách chuyển một đối tượng tuỳ chọn dưới dạng một tham số thứ hai.
const options = {
ignoreSearch: true,
ignoreMethod: true,
ignoreVary: true
};
const response = await cache.match(request, options);
// do something with the response
Nếu nhiều yêu cầu được lưu vào bộ nhớ đệm trùng khớp, thì yêu cầu được tạo đầu tiên là
bị trả lại. Nếu muốn truy xuất tất cả câu trả lời trùng khớp, bạn có thể sử dụng
cache.matchAll()
.
const options = {
ignoreSearch: true,
ignoreMethod: true,
ignoreVary: true
};
const responses = await cache.matchAll(request, options);
console.log(`There are ${responses.length} matching responses.`);
Khi dùng lối tắt, bạn có thể tìm kiếm trên tất cả bộ nhớ đệm cùng một lúc bằng caches.match()
thay vì gọi cache.match()
cho mỗi bộ nhớ đệm.
Đang tìm kiếm
Cache API không cung cấp cách tìm kiếm yêu cầu hoặc phản hồi
ngoại trừ việc khớp các mục nhập với đối tượng Response
. Tuy nhiên, bạn có thể
triển khai tìm kiếm của riêng bạn bằng cách sử dụng tính năng lọc hoặc tạo chỉ mục.
Lọc
Một cách để triển khai tìm kiếm của riêng bạn là lặp lại tất cả các mục nhập và
lọc ra những danh mục mà bạn muốn. Giả sử bạn muốn tìm tất cả
các mục có URL kết thúc bằng .png
.
async function findImages() {
// Get a list of all of the caches for this origin
const cacheNames = await caches.keys();
const result = [];
for (const name of cacheNames) {
// Open the cache
const cache = await caches.open(name);
// Get a list of entries. Each item is a Request object
for (const request of await cache.keys()) {
// If the request URL matches, add the response to the result
if (request.url.endsWith('.png')) {
result.push(await cache.match(request));
}
}
}
return result;
}
Bằng cách này, bạn có thể sử dụng bất kỳ thuộc tính nào của đối tượng Request
và Response
để
lọc các mục nhập. Xin lưu ý rằng sẽ chạy chậm nếu bạn tìm kiếm trên tập hợp lớn
.
Tạo chỉ mục
Cách khác để triển khai tìm kiếm của riêng bạn là duy trì chỉ mục riêng biệt của các mục nhập có thể tìm kiếm và lưu trữ chỉ mục trong IndexedDB. Vì đây là loại mà IndexedDB thiết kế để có hiệu suất tốt hơn nhiều với có rất nhiều bài viết.
Nếu bạn lưu trữ URL của Request
cùng với các thuộc tính có thể tìm kiếm
thì bạn có thể dễ dàng truy xuất đúng mục nhập trong bộ nhớ đệm sau khi tìm kiếm.
Xoá một mục
Cách xoá một mục khỏi bộ nhớ đệm:
cache.delete(request);
Trong đó, yêu cầu có thể là Request
hoặc một chuỗi URL. Phương thức này cũng lấy
đối tượng tuỳ chọn giống với cache.match
, cho phép bạn xoá nhiều
Request
/Response
cặp cho cùng một URL.
cache.delete('/example/file.txt', {ignoreVary: true, ignoreSearch: true});
Xoá bộ nhớ đệm
Để xoá bộ nhớ đệm, hãy gọi caches.delete(name)
. Hàm này trả về một
Promise
phân giải thành true
nếu bộ nhớ đệm đã tồn tại và đã bị xoá, hoặc
false
.
Cảm ơn bạn!
Nhờ Mat Scales, người đã viết phiên bản gốc của bài viết này mà xuất hiện đầu tiên trên WebBasics.