Với Trình chạy dịch vụ, chúng tôi đã ngừng cố gắng giải quyết chế độ ngoại tuyến và cung cấp cho nhà phát triển các phần chuyển động để tự giải quyết vấn đề. API này cho phép bạn kiểm soát việc lưu vào bộ nhớ đệm và cách xử lý yêu cầu. Điều đó có nghĩa là bạn có thể tạo các mẫu của riêng mình. Hãy cùng xem xét một vài mẫu có thể có khi tách riêng, nhưng trong thực tế, bạn có thể sẽ sử dụng nhiều mẫu cùng lúc tuỳ thuộc vào URL và ngữ cảnh.
Để xem bản minh hoạ hoạt động của một số mẫu này, hãy xem Trained-to-thrill và video này cho thấy tác động đến hiệu suất.
Máy bộ nhớ đệm – thời điểm lưu trữ tài nguyên
Trình chạy dịch vụ cho phép bạn xử lý các yêu cầu độc lập với việc lưu vào bộ nhớ đệm, vì vậy, tôi sẽ minh hoạ riêng về các yêu cầu này. Trước tiên, việc lưu vào bộ nhớ đệm nên được thực hiện khi nào?
Khi cài đặt – dưới dạng phần phụ thuộc
Trình chạy dịch vụ cung cấp cho bạn một sự kiện install
. Bạn có thể sử dụng phương thức này để chuẩn bị mọi thứ, những thứ phải sẵn sàng trước khi bạn xử lý các sự kiện khác. Trong khi điều này xảy ra, mọi phiên bản trước đó của Worker dịch vụ vẫn đang chạy và phân phát trang, vì vậy, những việc bạn làm ở đây không được làm gián đoạn việc đó.
Lý tưởng cho: CSS, hình ảnh, phông chữ, JS, mẫu, v.v. về cơ bản là bất kỳ thứ gì bạn cho là tĩnh đối với "phiên bản" đó của trang web.
Đây là những nội dung sẽ khiến trang web của bạn không hoạt động hoàn toàn nếu không được tìm nạp, những nội dung mà một ứng dụng tương đương dành riêng cho nền tảng sẽ đưa vào quá trình tải xuống ban đầu.
self.addEventListener('install', function (event) {
event.waitUntil(
caches.open('mysite-static-v3').then(function (cache) {
return cache.addAll([
'/css/whatever-v3.css',
'/css/imgs/sprites-v6.png',
'/css/fonts/whatever-v8.woff',
'/js/all-min-v4.js',
// etc.
]);
}),
);
});
event.waitUntil
thực hiện một lời hứa để xác định thời lượng và mức độ thành công của quá trình cài đặt. Nếu lời hứa bị từ chối, quá trình cài đặt sẽ bị coi là không thành công và Trình chạy dịch vụ này sẽ bị bỏ qua (nếu phiên bản cũ đang chạy, phiên bản đó sẽ được giữ nguyên). caches.open()
và cache.addAll()
trả về các lời hứa.
Nếu không tìm nạp được bất kỳ tài nguyên nào, lệnh gọi cache.addAll()
sẽ bị từ chối.
Trong các chương trình được huấn luyện từ trò chơi cảm giác mạnh, tôi sử dụng cách này để lưu tài sản tĩnh vào bộ nhớ đệm.
Khi cài đặt – không phải dưới dạng phần phụ thuộc
Cách này tương tự như trên, nhưng sẽ không trì hoãn quá trình cài đặt hoàn tất và sẽ không khiến quá trình cài đặt không thành công nếu không lưu vào bộ nhớ đệm.
Lý tưởng cho: những tài nguyên lớn hơn không cần dùng ngay, chẳng hạn như tài sản cho các cấp độ sau của trò chơi.
self.addEventListener('install', function (event) {
event.waitUntil(
caches.open('mygame-core-v1').then(function (cache) {
cache
.addAll
// levels 11–20
();
return cache
.addAll
// core assets and levels 1–10
();
}),
);
});
Ví dụ trên không chuyển lời hứa cache.addAll
cho các cấp 11–20 trở lại event.waitUntil
, vì vậy, ngay cả khi không thành công, trò chơi vẫn có thể chơi ngoại tuyến. Tất nhiên, bạn sẽ phải tính đến khả năng không có các cấp đó và thử lưu lại các cấp đó vào bộ nhớ đệm nếu các cấp đó bị thiếu.
Worker dịch vụ có thể bị tắt trong khi tải các cấp 11–20 xuống vì đã xử lý xong các sự kiện, nghĩa là các sự kiện đó sẽ không được lưu vào bộ nhớ đệm. Trong tương lai, API đồng bộ hoá nền định kỳ trên web sẽ xử lý các trường hợp tương tự và các tệp đã tải xuống với kích thước lớn hơn như phim. API đó hiện chỉ được hỗ trợ trên các nhánh Chromium.
Khi kích hoạt
Lý tưởng cho: dọn dẹp và di chuyển.
Sau khi cài đặt một Worker dịch vụ mới và phiên bản trước đó không được sử dụng, phiên bản mới sẽ kích hoạt và bạn sẽ nhận được một sự kiện activate
. Vì phiên bản cũ không còn được dùng nữa, nên đây là thời điểm thích hợp để xử lý việc di chuyển giản đồ trong IndexedDB và xoá bộ nhớ đệm không dùng đến.
self.addEventListener('activate', function (event) {
event.waitUntil(
caches.keys().then(function (cacheNames) {
return Promise.all(
cacheNames
.filter(function (cacheName) {
// Return true if you want to remove this cache,
// but remember that caches are shared across
// the whole origin
})
.map(function (cacheName) {
return caches.delete(cacheName);
}),
);
}),
);
});
Trong quá trình kích hoạt, các sự kiện khác như fetch
sẽ được đưa vào hàng đợi, vì vậy, việc kích hoạt lâu có thể chặn việc tải trang. Hãy kích hoạt ở mức tinh gọn nhất có thể và chỉ sử dụng cho những việc bạn không thể làm trong khi phiên bản cũ còn hoạt động.
Trong giai đoạn hướng dẫn về trò chơi cảm giác mạnh, tôi sử dụng cách này để xoá các bộ nhớ đệm cũ.
Về hoạt động tương tác của người dùng
Lý tưởng cho: khi không thể tải toàn bộ trang web xuống và bạn đã chọn cho phép người dùng chọn nội dung họ muốn xem khi không có mạng. Ví dụ: một video về những thứ gì đó như YouTube, một bài viết trên Wikipedia, một phòng trưng bày cụ thể trên Flickr.
Cung cấp cho người dùng nút "Đọc sau" hoặc "Lưu để đọc khi không có mạng". Khi được nhấp vào, hãy tìm nạp những gì bạn cần từ mạng và đưa vào bộ nhớ đệm.
document.querySelector('.cache-article').addEventListener('click', function (event) {
event.preventDefault();
var id = this.dataset.articleId;
caches.open('mysite-article-' + id).then(function (cache) {
fetch('/get-article-urls?id=' + id)
.then(function (response) {
// /get-article-urls returns a JSON-encoded array of
// resource URLs that a given article depends on
return response.json();
})
.then(function (urls) {
cache.addAll(urls);
});
});
});
API bộ nhớ đệm có sẵn trên các trang cũng như trình chạy dịch vụ, nghĩa là bạn có thể thêm vào bộ nhớ đệm ngay từ trang.
Về phản hồi mạng
Phù hợp với: các tài nguyên thường xuyên cập nhật, chẳng hạn như hộp thư đến của người dùng hoặc nội dung bài viết. Cũng rất hữu ích cho nội dung không cần thiết như hình đại diện, nhưng bạn cần phải cẩn thận.
Nếu một yêu cầu không khớp với bất kỳ nội dung nào trong bộ nhớ đệm, hãy lấy yêu cầu đó từ mạng, gửi yêu cầu tới trang rồi thêm yêu cầu vào bộ nhớ đệm cùng lúc.
Nếu thực hiện việc này cho một loạt URL, chẳng hạn như hình đại diện, bạn cần cẩn thận để không làm tăng dung lượng lưu trữ của nguồn gốc. Nếu người dùng cần lấy lại dung lượng ổ đĩa, bạn không nên là ứng cử viên chính. Hãy nhớ xoá những mục không cần thiết trong bộ nhớ đệm.
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.open('mysite-dynamic').then(function (cache) {
return cache.match(event.request).then(function (response) {
return (
response ||
fetch(event.request).then(function (response) {
cache.put(event.request, response.clone());
return response;
})
);
});
}),
);
});
Để sử dụng bộ nhớ hiệu quả, bạn chỉ có thể đọc nội dung của một phản hồi/yêu cầu một lần. Mã ở trên sử dụng .clone()
để tạo các bản sao bổ sung có thể đọc riêng.
Trên trained-to-thrill, tôi sử dụng tính năng này để lưu hình ảnh trên Flickr vào bộ nhớ đệm.
Stale-while-revalidate
Phù hợp với: các tài nguyên thường xuyên cập nhật mà không cần có phiên bản mới nhất. Hình đại diện có thể thuộc danh mục này.
Nếu có phiên bản được lưu vào bộ nhớ đệm, hãy sử dụng phiên bản đó, nhưng hãy tìm nạp bản cập nhật cho lần sau.
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.open('mysite-dynamic').then(function (cache) {
return cache.match(event.request).then(function (response) {
var fetchPromise = fetch(event.request).then(function (networkResponse) {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
return response || fetchPromise;
});
}),
);
});
Điều này rất giống với quy trình cũ trong khi xác thực lại của HTTP.
Trên thông báo đẩy
Push API là một tính năng khác được xây dựng dựa trên Service Worker. Điều này cho phép đánh thức Worker dịch vụ để phản hồi một thông báo từ dịch vụ nhắn tin của hệ điều hành. Điều này xảy ra ngay cả khi người dùng không mở thẻ nào để truy cập vào trang web của bạn. Chỉ có Service Worker được đánh thức. Bạn yêu cầu quyền để làm việc này từ một trang và người dùng sẽ được nhắc.
Phù hợp cho: nội dung liên quan đến một thông báo, chẳng hạn như tin nhắn trò chuyện, tin nổi bật hoặc email. Ngoài ra, nội dung thay đổi không thường xuyên sẽ được hưởng lợi từ tính năng đồng bộ hoá tức thì, chẳng hạn như nội dung cập nhật danh sách việc cần làm hoặc nội dung thay đổi lịch.
Kết quả cuối cùng phổ biến là một thông báo mà khi được nhấn vào sẽ mở/tập trung vào một trang có liên quan, nhưng việc cập nhật bộ nhớ đệm trước khi điều này xảy ra cực kỳ quan trọng. Rõ ràng là người dùng đang trực tuyến tại thời điểm nhận được thông báo đẩy, nhưng có thể họ không trực tuyến khi cuối cùng tương tác với thông báo. Vì vậy, việc cung cấp nội dung này khi không có mạng là rất quan trọng.
Mã này cập nhật bộ nhớ đệm trước khi hiển thị thông báo:
self.addEventListener('push', function (event) {
if (event.data.text() == 'new-email') {
event.waitUntil(
caches
.open('mysite-dynamic')
.then(function (cache) {
return fetch('/inbox.json').then(function (response) {
cache.put('/inbox.json', response.clone());
return response.json();
});
})
.then(function (emails) {
registration.showNotification('New email', {
body: 'From ' + emails[0].from.name,
tag: 'new-email',
});
}),
);
}
});
self.addEventListener('notificationclick', function (event) {
if (event.notification.tag == 'new-email') {
// Assume that all of the resources needed to render
// /inbox/ have previously been cached, e.g. as part
// of the install handler.
new WindowClient('/inbox/');
}
});
Trên background-sync
Đồng bộ hoá ở chế độ nền là một tính năng khác được xây dựng dựa trên Service Worker. API này cho phép bạn yêu cầu đồng bộ hoá dữ liệu ở chế độ nền một lần hoặc theo khoảng thời gian (cực kỳ phỏng đoán). Điều này xảy ra ngay cả khi người dùng không mở thẻ nào đến trang web của bạn. Chỉ có Trình chạy dịch vụ được đánh thức. Bạn yêu cầu cấp quyền để thực hiện việc này trên một trang và người dùng sẽ được nhắc.
Phù hợp cho: các nội dung cập nhật không khẩn cấp, đặc biệt là những nội dung cập nhật xảy ra thường xuyên đến mức người dùng thường xuyên nhận được thông báo đẩy trên mỗi bản cập nhật (chẳng hạn như dòng thời gian trên mạng xã hội hoặc tin bài).
self.addEventListener('sync', function (event) {
if (event.id == 'update-leaderboard') {
event.waitUntil(
caches.open('mygame-dynamic').then(function (cache) {
return cache.add('/leaderboard.json');
}),
);
}
});
Lưu trữ cố định vào bộ nhớ đệm
Nguồn gốc của bạn được cấp một lượng dung lượng trống nhất định để làm những gì nó muốn. Dung lượng trống đó được chia sẻ giữa tất cả bộ nhớ gốc: Bộ nhớ(miền cục bộ), IndexedDB, Quyền truy cập vào hệ thống tệp và tất nhiên là Bộ nhớ đệm.
Số tiền bạn nhận được không được chỉ định. Số liệu này sẽ khác nhau tuỳ thuộc vào thiết bị và điều kiện lưu trữ. Bạn có thể tìm hiểu số tiền mình nhận được thông qua:
if (navigator.storage && navigator.storage.estimate) {
const quota = await navigator.storage.estimate();
// quota.usage -> Number of bytes used.
// quota.quota -> Maximum number of bytes available.
const percentageUsed = (quota.usage / quota.quota) * 100;
console.log(`You've used ${percentageUsed}% of the available storage.`);
const remaining = quota.quota - quota.usage;
console.log(`You can write up to ${remaining} more bytes.`);
}
Tuy nhiên, giống như mọi bộ nhớ của trình duyệt, trình duyệt có thể xoá dữ liệu của bạn nếu thiết bị bị áp lực về bộ nhớ. Rất tiếc, trình duyệt không thể phân biệt giữa những bộ phim mà bạn muốn giữ lại bằng mọi giá và trò chơi mà bạn không thực sự quan tâm.
Để giải quyết vấn đề này, hãy sử dụng giao diện StorageManager:
// From a page:
navigator.storage.persist()
.then(function(persisted) {
if (persisted) {
// Hurrah, your data is here to stay!
} else {
// So sad, your data may get chucked. Sorry.
});
Tất nhiên, người dùng phải cấp quyền. Để thực hiện việc này, hãy sử dụng API Quyền.
Việc đưa người dùng vào quy trình này là rất quan trọng vì giờ đây, chúng ta có thể cho phép họ kiểm soát việc xoá. Nếu thiết bị của họ bị áp lực về bộ nhớ và việc xoá dữ liệu không cần thiết không giải quyết được vấn đề, thì người dùng sẽ đánh giá những mục cần giữ lại và xoá.
Để tính năng này hoạt động, hệ điều hành phải coi các nguồn gốc "bền vững" tương đương với các ứng dụng dành riêng cho nền tảng trong bảng chi tiết về mức sử dụng bộ nhớ, thay vì báo cáo trình duyệt dưới dạng một mục duy nhất.
Đề xuất phân phát – phản hồi yêu cầu
Lượng dữ liệu lưu vào bộ nhớ đệm không quan trọng, worker dịch vụ sẽ không sử dụng bộ nhớ đệm trừ phi bạn cho biết thời điểm và cách thức. Dưới đây là một số mẫu để xử lý yêu cầu:
Chỉ bộ nhớ đệm
Loại hình phù hợp: mọi nội dung mà bạn coi là tĩnh đối với một "phiên bản" cụ thể của trang web. Bạn nên lưu các tệp này vào bộ nhớ đệm trong sự kiện cài đặt để có thể dựa vào các tệp đó.
self.addEventListener('fetch', function (event) {
// If a match isn't found in the cache, the response
// will look like a connection error
event.respondWith(caches.match(event.request));
});
…mặc dù bạn thường không cần xử lý trường hợp này một cách cụ thể, nhưng phần Bộ nhớ đệm, quay lại mạng sẽ đề cập đến trường hợp này.
Chỉ với mạng
Phù hợp với: những nội dung không có nội dung tương đương ngoại tuyến, chẳng hạn như ping phân tích, yêu cầu không phải GET.
self.addEventListener('fetch', function (event) {
event.respondWith(fetch(event.request));
// or simply don't call event.respondWith, which
// will result in default browser behavior
});
…mặc dù bạn thường không cần xử lý trường hợp này một cách cụ thể, nhưng phần Bộ nhớ đệm, quay lại mạng sẽ đề cập đến trường hợp này.
Bộ nhớ đệm, quay lại mạng
Lý tưởng cho: xây dựng chế độ ngoại tuyến. Trong những trường hợp như vậy, bạn sẽ xử lý phần lớn các yêu cầu theo cách sau. Các mẫu khác sẽ là ngoại lệ dựa trên yêu cầu sắp tới.
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.match(event.request).then(function (response) {
return response || fetch(event.request);
}),
);
});
Điều này cung cấp cho bạn hành vi "chỉ bộ nhớ đệm" cho những nội dung trong bộ nhớ đệm và hành vi "chỉ mạng" cho mọi nội dung không được lưu vào bộ nhớ đệm (bao gồm tất cả các yêu cầu không phải GET vì không thể lưu vào bộ nhớ đệm).
Cuộc đua giữa bộ nhớ đệm và mạng
Lý tưởng cho: những tài sản nhỏ mà bạn đang cần theo đuổi hiệu suất trên những thiết bị có quyền truy cập ổ đĩa chậm.
Với một số tổ hợp ổ đĩa cứng cũ, trình quét vi-rút và kết nối Internet nhanh hơn, việc tải tài nguyên qua mạng có thể nhanh hơn so với việc truy cập vào ổ đĩa. Tuy nhiên, việc truy cập vào mạng khi người dùng có nội dung trên thiết bị có thể gây lãng phí dữ liệu, vì vậy, hãy lưu ý điều đó.
// Promise.race is no good to us because it rejects if
// a promise rejects before fulfilling. Let's make a proper
// race function:
function promiseAny(promises) {
return new Promise((resolve, reject) => {
// make sure promises are all promises
promises = promises.map((p) => Promise.resolve(p));
// resolve this promise as soon as one resolves
promises.forEach((p) => p.then(resolve));
// reject if all promises reject
promises.reduce((a, b) => a.catch(() => b)).catch(() => reject(Error('All failed')));
});
}
self.addEventListener('fetch', function (event) {
event.respondWith(promiseAny([caches.match(event.request), fetch(event.request)]));
});
Mạng quay lại bộ nhớ đệm
Loại hình phù hợp: bản sửa lỗi nhanh cho các tài nguyên cập nhật thường xuyên, nằm ngoài "phiên bản" của trang web. Ví dụ: bài viết, hình đại diện, dòng thời gian trên mạng xã hội và bảng xếp hạng trò chơi.
Điều này có nghĩa là bạn cung cấp nội dung mới nhất cho người dùng trực tuyến, nhưng người dùng ngoại tuyến sẽ nhận được phiên bản cũ hơn được lưu vào bộ nhớ đệm. Nếu yêu cầu mạng thành công, rất có thể bạn sẽ muốn cập nhật mục nhập bộ nhớ đệm.
Tuy nhiên, phương thức này có một số điểm yếu. Nếu người dùng có kết nối không ổn định hoặc chậm, họ sẽ phải đợi mạng bị lỗi trước khi nhận được nội dung hoàn toàn chấp nhận được trên thiết bị của mình. Quá trình này có thể mất rất nhiều thời gian và gây ra trải nghiệm khó chịu cho người dùng. Hãy xem mẫu tiếp theo, Lưu vào bộ nhớ đệm rồi đến mạng, để biết giải pháp tốt hơn.
self.addEventListener('fetch', function (event) {
event.respondWith(
fetch(event.request).catch(function () {
return caches.match(event.request);
}),
);
});
Bộ nhớ đệm rồi đến mạng
Phù hợp với: nội dung được cập nhật thường xuyên. Ví dụ: bài viết, dòng thời gian trên mạng xã hội và bảng xếp hạng trò chơi.
Điều này đòi hỏi trang phải thực hiện hai yêu cầu, một yêu cầu đến bộ nhớ đệm và một yêu cầu đến mạng. Ý tưởng là trước tiên, hãy hiển thị dữ liệu đã lưu vào bộ nhớ đệm, sau đó cập nhật trang khi/nếu dữ liệu mạng đến.
Đôi khi, bạn chỉ cần thay thế dữ liệu hiện tại khi dữ liệu mới đến (ví dụ: bảng xếp hạng trò chơi), nhưng điều này có thể gây gián đoạn đối với các nội dung lớn hơn. Về cơ bản, đừng "biến mất" nội dung mà người dùng có thể đang đọc hoặc tương tác.
Twitter thêm nội dung mới phía trên nội dung cũ và điều chỉnh vị trí cuộn để người dùng không bị gián đoạn. Điều này có thể xảy ra vì Twitter chủ yếu giữ nguyên thứ tự nội dung theo tuyến tính. Tôi đã sao chép mẫu này cho trained-to-thrill để hiển thị nội dung trên màn hình nhanh nhất có thể, đồng thời hiển thị nội dung mới nhất ngay khi nội dung đó đến.
Mã trong trang:
var networkDataReceived = false;
startSpinner();
// fetch fresh data
var networkUpdate = fetch('/data.json')
.then(function (response) {
return response.json();
})
.then(function (data) {
networkDataReceived = true;
updatePage(data);
});
// fetch cached data
caches
.match('/data.json')
.then(function (response) {
if (!response) throw Error('No data');
return response.json();
})
.then(function (data) {
// don't overwrite newer network data
if (!networkDataReceived) {
updatePage(data);
}
})
.catch(function () {
// we didn't get cached data, the network is our last hope:
return networkUpdate;
})
.catch(showErrorMessage)
.then(stopSpinner);
Mã trong Service Worker:
Bạn nên luôn truy cập mạng và cập nhật bộ nhớ đệm khi thực hiện.
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.open('mysite-dynamic').then(function (cache) {
return fetch(event.request).then(function (response) {
cache.put(event.request, response.clone());
return response;
});
}),
);
});
Trong phần được huấn luyện đến kịch tính, tôi đã giải quyết vấn đề này bằng cách sử dụng XHR thay vì tìm nạp và lạm dụng tiêu đề Accept để cho Trình chạy dịch vụ biết nơi lấy kết quả (mã trang, mã Trình chạy dịch vụ).
Dự phòng chung
Nếu không phân phát được nội dung nào đó từ bộ nhớ đệm và/hoặc mạng, bạn nên cung cấp một phương án dự phòng chung.
Loại hình ảnh phù hợp: hình ảnh phụ như hình đại diện, yêu cầu POST không thành công và trang "Không có sẵn khi ngoại tuyến".
self.addEventListener('fetch', function (event) {
event.respondWith(
// Try the cache
caches
.match(event.request)
.then(function (response) {
// Fall back to network
return response || fetch(event.request);
})
.catch(function () {
// If both fail, show a generic fallback:
return caches.match('/offline.html');
// However, in reality you'd have many different
// fallbacks, depending on URL and headers.
// Eg, a fallback silhouette image for avatars.
}),
);
});
Mục bạn dự phòng có thể là phần phụ thuộc cài đặt.
Nếu trang của bạn đang đăng email, thì worker dịch vụ có thể quay lại lưu trữ email trong "hộp thư đi" IndexedDB và phản hồi bằng cách cho trang biết rằng quá trình gửi không thành công nhưng dữ liệu đã được giữ lại thành công.
Tạo mẫu phía worker dịch vụ
Lý tưởng cho: những trang không thể lưu phản hồi của máy chủ vào bộ nhớ đệm.
Việc hiển thị trang trên máy chủ giúp mọi thứ diễn ra nhanh chóng, nhưng điều đó có thể có nghĩa là bao gồm cả dữ liệu trạng thái có thể không có ý nghĩa trong bộ nhớ đệm, ví dụ: "Đã đăng nhập dưới dạng…". Nếu trang của bạn do một trình chạy dịch vụ kiểm soát, thì bạn có thể chọn yêu cầu dữ liệu JSON cùng với một mẫu và hiển thị dữ liệu đó.
importScripts('templating-engine.js');
self.addEventListener('fetch', function (event) {
var requestURL = new URL(event.request.url);
event.respondWith(
Promise.all([
caches.match('/article-template.html').then(function (response) {
return response.text();
}),
caches.match(requestURL.path + '.json').then(function (response) {
return response.json();
}),
]).then(function (responses) {
var template = responses[0];
var data = responses[1];
return new Response(renderTemplate(template, data), {
headers: {
'Content-Type': 'text/html',
},
});
}),
);
});
Tổng hợp kiến thức đã học
Bạn không bị giới hạn ở một trong những phương thức này. Trên thực tế, có thể bạn sẽ sử dụng nhiều biến tuỳ thuộc vào URL yêu cầu. Ví dụ: từ huấn luyện đến chơi cảm giác mạnh sử dụng:
- bộ nhớ đệm khi cài đặt cho giao diện người dùng và hành vi tĩnh
- lưu vào bộ nhớ đệm khi phản hồi mạng, đối với hình ảnh và dữ liệu trên Flickr
- tìm nạp từ bộ nhớ đệm, quay lại mạng, đối với hầu hết các yêu cầu
- tìm nạp từ bộ nhớ đệm, sau đó chọn mạng, cho các kết quả tìm kiếm trên Flickr
Bạn chỉ cần xem yêu cầu đó và quyết định việc nên làm:
self.addEventListener('fetch', function (event) {
// Parse the URL:
var requestURL = new URL(event.request.url);
// Handle requests to a particular host specifically
if (requestURL.hostname == 'api.example.com') {
event.respondWith(/* some combination of patterns */);
return;
}
// Routing for local URLs
if (requestURL.origin == location.origin) {
// Handle article URLs
if (/^\/article\//.test(requestURL.pathname)) {
event.respondWith(/* some other combination of patterns */);
return;
}
if (/\.webp$/.test(requestURL.pathname)) {
event.respondWith(/* some other combination of patterns */);
return;
}
if (request.method == 'POST') {
event.respondWith(/* some other combination of patterns */);
return;
}
if (/cheese/.test(requestURL.pathname)) {
event.respondWith(
new Response('Flagrant cheese error', {
status: 512,
}),
);
return;
}
}
// A sensible default pattern
event.respondWith(
caches.match(event.request).then(function (response) {
return response || fetch(event.request);
}),
);
});
…bạn hiểu ý tôi rồi.
Ghi công
…cho các biểu tượng đáng yêu:
- Mã của buzzyrobot
- Calendar của Scott Lewis
- Network by Ben Rizzo
- SD của Thomas Le Bas
- CPU của iconsmind.com
- Thùng rác của trasnik
- Thông báo của @daosme
- Layout của Mister Pixel
- Cloud của P.J. Onori
Cảm ơn Jeff Posnick đã phát hiện nhiều lỗi nghiêm trọng trước khi tôi nhấn vào nút "xuất bản".
Tài liệu đọc thêm
- Trình chạy dịch vụ – Giới thiệu
- Service Worker đã sẵn sàng chưa? – theo dõi trạng thái triển khai trên các trình duyệt chính
- JavaScript Promises – Giới thiệu – hướng dẫn về lời hứa