Trình chạy dịch vụ có thể chặn các yêu cầu mạng cho một trang. Trợ lý có thể phản hồi với trình duyệt có nội dung được lưu vào bộ nhớ đệm, nội dung từ mạng hoặc nội dung được tạo trong trình chạy dịch vụ.
workbox-routing
là một mô-đun giúp bạn dễ dàng "định tuyến" những yêu cầu này đến
các hàm khác nhau cung cấp phản hồi.
Cách thực hiện việc định tuyến
Khi một yêu cầu mạng gây ra sự kiện tìm nạp trình chạy dịch vụ, workbox-routing
sẽ cố gắng phản hồi yêu cầu bằng các tuyến và trình xử lý được cung cấp.
Những điều chính cần lưu ý ở trên là:
Phương thức của yêu cầu là một yếu tố quan trọng. Theo mặc định, Tuyến đường được đăng ký cho
GET
yêu cầu. Nếu muốn chặn các loại yêu cầu khác, bạn cần để chỉ định phương thức.Thứ tự đăng ký Tuyến đường là rất quan trọng. Nếu có nhiều Tuyến đường đã đăng ký có thể xử lý yêu cầu, Tuyến được đăng ký trước sẽ được dùng để phản hồi yêu cầu.
Có một số cách để đăng ký một tuyến: bạn có thể sử dụng các lệnh gọi lại, biểu thức hoặc bản sao Tuyến đường.
So khớp và xử lý trong tuyến đường
Một "tuyến đường" trong hộp công việc chỉ là hai chức năng: "phù hợp" hàm để xác định xem tuyến đường có phù hợp với yêu cầu và "xử lý" không hàm, sẽ xử lý yêu cầu và phản hồi bằng một phản hồi.
Workbox đi kèm với một số trình trợ giúp sẽ thực hiện việc so khớp và xử lý bạn, nhưng nếu bạn muốn có một hành vi khác, hãy viết kết hợp tuỳ chỉnh và chức năng trình xử lý là lựa chọn tốt nhất.
Đáp
khớp hàm callback
được truyền một
ExtendableEvent
!
Request
và một
URL
đối tượng bạn có thể
bằng cách trả về một giá trị trung thực. Ví dụ đơn giản: bạn có thể so khớp với
một URL cụ thể, chẳng hạn như:
const matchCb = ({url, request, event}) => {
return url.pathname === '/special/url';
};
Hầu hết các trường hợp sử dụng đều có thể được kiểm tra bằng cách kiểm tra / kiểm thử url
hoặc
request
Đáp
hàm callback xử lý
sẽ được cấp cùng một
ExtendableEvent
!
Request
và
URL
đối tượng cùng với
giá trị params
, là giá trị được lệnh "khớp" trả về .
const handlerCb = async ({url, request, event, params}) => {
const response = await fetch(request);
const responseBody = await response.text();
return new Response(`${responseBody} <!-- Look Ma. Added Content. -->`, {
headers: response.headers,
});
};
Trình xử lý của bạn phải trả về một lời hứa phân giải thành Response
. Trong phần này
Ví dụ: chúng tôi đang sử dụng
async
và await
.
Về sau, giá trị Response
trả về sẽ được gói gọn trong một lời hứa.
Bạn có thể đăng ký các lệnh gọi lại này như sau:
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb);
Hạn chế duy nhất là "sự trùng khớp" lệnh gọi lại phải đồng bộ trả về giá trị trung thực
, bạn không thể thực hiện bất kỳ công việc không đồng bộ nào. Lý do là
Router
phải phản hồi một cách đồng bộ với sự kiện tìm nạp hoặc cho phép rơi
đến các sự kiện tìm nạp khác.
Thường là "handler" lệnh gọi lại sẽ sử dụng một trong các chiến lược được cung cấp theo workbox-strategy như sau:
import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
registerRoute(matchCb, new StaleWhileRevalidate());
Trong trang này, chúng tôi sẽ tập trung vào workbox-routing
nhưng bạn có thể
tìm hiểu thêm về các chiến lược này đối với các chiến lược hộp công việc.
Cách đăng ký tuyến biểu thức chính quy
Phương pháp phổ biến là sử dụng biểu thức chính quy thay vì "so khớp" . Workbox giúp bạn dễ dàng triển khai như sau:
import {registerRoute} from 'workbox-routing';
registerRoute(new RegExp('/styles/.*\\.css'), handlerCb);
Đối với các yêu cầu từ cùng nguồn gốc, biểu thức chính quy này sẽ khớp miễn là URL của yêu cầu khớp với biểu thức chính quy.
- https://example.com/styles/main.css
- https://example.com/styles/nested/file.css
- https://example.com/nested/styles/directory.css
Tuy nhiên, đối với các yêu cầu trên nhiều nguồn gốc, biểu thức chính quy
phải khớp với phần đầu của URL. Lý do là vì
không chắc chắn rằng với biểu thức chính quy new RegExp('/styles/.*\\.css')
mà bạn dự định so khớp với các tệp CSS của bên thứ ba.
- https://cdn.third-party-site.com/styles/main.css
- https://cdn.third-party-site.com/styles/nested/file.css
- https://cdn.third-party-site.com/nested/styles/directory.css
Nếu có muốn hành vi này, bạn chỉ cần đảm bảo rằng quy tắc
khớp với phần đầu của URL. Nếu chúng tôi muốn phù hợp với
cho https://cdn.third-party-site.com
, chúng ta có thể sử dụng toán tử thông thường
biểu thức new RegExp('https://cdn\\.third-party-site\\.com.*/styles/.*\\.css')
.
- https://cdn.third-party-site.com/styles/main.css
- https://cdn.third-party-site.com/styles/nested/file.css
- https://cdn.third-party-site.com/nested/styles/directory.css
Nếu muốn so khớp với cả bên địa phương và bên thứ ba, bạn có thể sử dụng ký tự đại diện ở đầu biểu thức chính quy, nhưng bạn nên thận trọng khi thực hiện thao tác này để đảm bảo không gây ra hành vi không mong muốn trong ứng dụng web của bạn.
Cách đăng ký tuyến đường điều hướng
Nếu trang web của bạn là ứng dụng trang đơn, bạn có thể sử dụng
NavigationRoute
đến
trả về một phản hồi cụ thể cho tất cả
yêu cầu chỉ đường.
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';
// This assumes /app-shell.html has been precached.
const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler);
registerRoute(navigationRoute);
Bất cứ khi nào người dùng truy cập vào trang web của bạn trong trình duyệt, yêu cầu cho trang đó sẽ
là yêu cầu điều hướng và nó sẽ được phân phát trang được lưu vào bộ nhớ đệm /app-shell.html
.
(Lưu ý: Bạn nên lưu trang vào bộ nhớ đệm qua workbox-precaching
hoặc qua
bước cài đặt riêng).
Theo mặc định, lệnh này sẽ phản hồi tất cả các yêu cầu điều hướng. Nếu bạn muốn
để hạn chế lệnh đó phản hồi một nhóm nhỏ URL, bạn có thể sử dụng allowlist
và denylist
để hạn chế những trang nào sẽ khớp với tuyến này.
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';
// This assumes /app-shell.html has been precached.
const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
allowlist: [new RegExp('/blog/')],
denylist: [new RegExp('/blog/restricted/')],
});
registerRoute(navigationRoute);
Điều duy nhất cần lưu ý là denylist
sẽ giành chiến thắng nếu một URL nằm trong cả hai
allowlist
và denylist
.
Đặt trình xử lý mặc định
Nếu bạn muốn cung cấp "xử lý" cho các yêu cầu không khớp với một tuyến đường, bạn có thể đặt trình xử lý mặc định.
import {setDefaultHandler} from 'workbox-routing';
setDefaultHandler(({url, event, params}) => {
// ...
});
Đặt trình xử lý bắt
Trong trường hợp bất kỳ tuyến đường nào của bạn bị lỗi, bạn có thể ghi lại và hãy xuống cấp nhẹ bằng cách thiết lập trình xử lý bắt.
import {setCatchHandler} from 'workbox-routing';
setCatchHandler(({url, event, params}) => {
...
});
Xác định tuyến cho các yêu cầu không phải GET
Theo mặc định, tất cả các tuyến đều dành cho các yêu cầu GET
.
Nếu muốn định tuyến các yêu cầu khác, chẳng hạn như yêu cầu POST
, bạn cần
để xác định phương thức khi đăng ký tuyến, như sau:
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb, 'POST');
registerRoute(new RegExp('/api/.*\\.json'), handlerCb, 'POST');
Ghi nhật ký bộ định tuyến
Bạn phải xác định được luồng yêu cầu bằng cách sử dụng nhật ký từ
workbox-routing
sẽ đánh dấu những URL đang được xử lý
thông qua Workbox.
Nếu cần thông tin chi tiết hơn, bạn có thể đặt cấp độ nhật ký thành debug
thành
xem nhật ký trên các yêu cầu không được Bộ định tuyến xử lý. Xem
hướng dẫn gỡ lỗi để biết thêm thông tin về
đặt cấp độ nhật ký.
Cách sử dụng nâng cao
Nếu bạn muốn có nhiều quyền kiểm soát hơn đối với thời điểm Bộ định tuyến hộp làm việc được cung cấp
các yêu cầu của riêng mình, bạn có thể tạo
Thực thể và lệnh gọi Router
thời điểm hiện tại là handleRequest()
bất cứ khi nào bạn muốn sử dụng bộ định tuyến để phản hồi một yêu cầu.
import {Router} from 'workbox-routing';
const router = new Router();
self.addEventListener('fetch', event => {
const {request} = event;
const responsePromise = router.handleRequest({
event,
request,
});
if (responsePromise) {
// Router found a route to handle the request.
event.respondWith(responsePromise);
} else {
// No route was found to handle the request.
}
});
Khi sử dụng trực tiếp Router
, bạn cũng cần dùng lớp Route
,
hoặc bất kỳ lớp mở rộng nào để đăng ký tuyến.
import {Route, RegExpRoute, NavigationRoute, Router} from 'workbox-routing';
const router = new Router();
router.registerRoute(new Route(matchCb, handlerCb));
router.registerRoute(new RegExpRoute(new RegExp(...), handlerCb));
router.registerRoute(new NavigationRoute(handlerCb));
Loại
NavigationRoute
NavigationRoute giúp bạn dễ dàng tạo
workbox-routing.Route
phù hợp với trình duyệt
[yêu cầu chỉ đường]https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests
.
Yêu cầu này sẽ chỉ khớp với các Yêu cầu đến có
https://fetch.spec.whatwg.org/#concept-request-mode|mode
được đặt thành navigate
.
Bạn chỉ có thể áp dụng tuyến này cho một số yêu cầu chỉ đường (không bắt buộc)
bằng cách sử dụng một hoặc cả hai tham số denylist
và allowlist
.
Thuộc tính
-
void
Nếu bạn cung cấp cả
denylist
vàallowlist
, thìdenylist
sẽ sẽ được ưu tiên và yêu cầu sẽ không khớp với tuyến này.Biểu thức chính quy trong
allowlist
vàdenylist
khớp với các chuỗi được nối [pathname
]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname
và [search
]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search
của URL được yêu cầu.Lưu ý: Các RegExps này có thể được đánh giá dựa trên mọi URL đích trong khoảng thời gian điều hướng. Tránh sử dụng RegExps phức tạp, nếu không, người dùng có thể gặp phải sự chậm trễ khi điều hướng trang web của bạn.
Hàm
constructor
có dạng như sau:(handler: RouteHandler, options?: NavigationRouteMatchOptions) => {...}
-
Lệnh gọi lại hàm trả về Lời hứa dẫn đến Phản hồi.
-
NavigationRouteMatchOptions không bắt buộc
-
-
RouteHandlerObject không bắt buộc
-
HTTPMethod
-
void
Hàm
setCatchHandler
có dạng như sau:(handler: RouteHandler) => {...}
-
Lệnh gọi lại hàm trả về một Promise phân giải cho một Phản hồi
-
NavigationRouteMatchOptions
Thuộc tính
-
RegExp[] không bắt buộc
-
RegExp[] không bắt buộc
RegExpRoute
RegExpRoute giúp bạn dễ dàng tạo biểu thức chính quy dựa trên
workbox-routing.Route
.
Đối với các yêu cầu cùng nguồn gốc, RegExp chỉ cần khớp với một phần của URL. Cho đối với máy chủ của bên thứ ba, bạn phải xác định RegExp phù hợp với phần đầu của URL.
Thuộc tính
-
hàm khởi tạo
void
Nếu biểu thức chính quy chứa [nhóm chụp]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references
, các giá trị đã thu thập sẽ được chuyển đếnparams
workbox-routing~handlerCallback
đối số.Hàm
constructor
có dạng như sau:(regExp: RegExp, handler: RouteHandler, method?: HTTPMethod) => {...}
-
regExp
RegExp
Biểu thức chính quy để so khớp với URL.
-
trình xử lý
Lệnh gọi lại hàm trả về Lời hứa dẫn đến Phản hồi.
-
method
HTTPMethod không bắt buộc
-
returns
-
-
catchHandler
RouteHandlerObject không bắt buộc
-
trình xử lý
-
phù hợp
-
method
HTTPMethod
-
setCatchHandler
void
Hàm
setCatchHandler
có dạng như sau:(handler: RouteHandler) => {...}
-
trình xử lý
Lệnh gọi lại hàm trả về một Promise phân giải cho một Phản hồi
-
Route
Route
bao gồm một cặp hàm callback là "match" ("khớp") và "handler".
"Trùng khớp" lệnh gọi lại xác định xem có nên sử dụng một tuyến để "xử lý" hay không một
bằng cách trả về một giá trị không sai (nếu có thể). "Người xử lý" số gọi lại
được gọi khi có kết quả trùng khớp và sẽ trả về một Lời hứa đã giải quyết
thành Response
.
Thuộc tính
-
hàm khởi tạo
void
Hàm khởi tạo cho lớp Tuyến đường.
Hàm
constructor
có dạng như sau:(match: RouteMatchCallback, handler: RouteHandler, method?: HTTPMethod) => {...}
-
phù hợp
Hàm callback xác định xem tuyến có khớp với một hàm đã cho hay không
fetch
bằng cách trả về một giá trị không giả. -
trình xử lý
Lệnh gọi lại hàm trả về một Promise phân giải cho một Phản hồi.
-
method
HTTPMethod không bắt buộc
-
returns
-
-
catchHandler
RouteHandlerObject không bắt buộc
-
trình xử lý
-
phù hợp
-
method
HTTPMethod
-
setCatchHandler
void
Hàm
setCatchHandler
có dạng như sau:(handler: RouteHandler) => {...}
-
trình xử lý
Lệnh gọi lại hàm trả về một Promise phân giải cho một Phản hồi
-
Router
Bạn có thể dùng Bộ định tuyến để xử lý FetchEvent
bằng một hoặc nhiều
workbox-routing.Route
, phản hồi bằng Response
nếu
tuyến đường phù hợp đã tồn tại.
Nếu không có tuyến nào khớp với một yêu cầu đã cho, Bộ định tuyến sẽ sử dụng giá trị "mặc định" nếu một trình xử lý được xác định.
Nếu Tuyến đường phù hợp gửi lỗi, Bộ định tuyến sẽ sử dụng "catch" nếu một trình xử lý được xác định là xử lý linh hoạt các vấn đề và phản hồi bằng Yêu cầu.
Nếu một yêu cầu khớp với nhiều tuyến, thì tuyến đường được đăng ký sớm nhất sẽ để phản hồi yêu cầu.
Thuộc tính
-
hàm khởi tạo
void
Khởi chạy Bộ định tuyến mới.
Hàm
constructor
có dạng như sau:() => {...}
-
returns
-
-
tuyến đường
Map<HTTPMethodRoute[]>
-
addCacheListener
void
Thêm trình nghe sự kiện thông báo cho các URL để lưu vào bộ nhớ đệm trong cửa sổ. Điều này rất hữu ích để lưu các tài nguyên vào bộ nhớ đệm được tải trên trang trước khi Service worker đã bắt đầu kiểm soát nó.
Định dạng của dữ liệu tin nhắn được gửi từ cửa sổ phải như sau. Trong đó mảng
urlsToCache
có thể bao gồm các chuỗi URL hoặc một mảng Chuỗi URL + đối tượngrequestInit
(giống như cách bạn truyền đếnfetch()
).{ type: 'CACHE_URLS', payload: { urlsToCache: [ './script1.js', './script2.js', ['./script3.js', {mode: 'no-cors'}], ], }, }
Hàm
addCacheListener
có dạng như sau:() => {...}
-
addFetchListener
void
Thêm trình nghe sự kiện tìm nạp để phản hồi các sự kiện khi một tuyến khớp yêu cầu của sự kiện.
Hàm
addFetchListener
có dạng như sau:() => {...}
-
findMatchingRoute
void
Kiểm tra yêu cầu và URL (và một sự kiện không bắt buộc) so với danh sách các tuyến đã đăng ký và nếu có kết quả trùng khớp, hàm sẽ trả về giá trị cùng với mọi tham số do việc so khớp tạo ra.
Hàm
findMatchingRoute
có dạng như sau:(options: RouteMatchCallbackOptions) => {...}
-
tùy chọn
-
returns
đối tượng
Một đối tượng có các thuộc tính
route
vàparams
. Các đường dẫn này sẽ được điền sẵn nếu tìm thấy một tuyến đường trùng khớp hoặcundefined
nếu không.
-
-
handleRequest
void
Áp dụng các quy tắc định tuyến cho một đối tượng FetchEvent để nhận Phản hồi từ một đối tượng trình xử lý của Tuyến đường thích hợp.
Hàm
handleRequest
có dạng như sau:(options: object) => {...}
-
tùy chọn
đối tượng
-
event
ExtendableEvent
Sự kiện đã kích hoạt của bạn.
-
request
Yêu cầu
Yêu cầu xử lý.
-
-
returns
Promise<Response>
Lời hứa được trả lại nếu có thể xử lý yêu cầu. Nếu không có mã nào phù hợp tuyến và không có
defaultHandler
, thì kết quả trả về làundefined
.
-
-
registerRoute
void
Đăng ký một tuyến với bộ định tuyến.
Hàm
registerRoute
có dạng như sau:(route: Route) => {...}
-
tuyến đường
Tuyến đường đăng ký.
-
-
setCatchHandler
void
Nếu Tuyến đường gửi lỗi trong khi xử lý yêu cầu, thì
handler
này sẽ được gọi và cho bạn cơ hội phản hồi.Hàm
setCatchHandler
có dạng như sau:(handler: RouteHandler) => {...}
-
trình xử lý
Lệnh gọi lại hàm trả về Lời hứa dẫn đến Phản hồi.
-
-
setDefaultHandler
void
Xác định
handler
mặc định được gọi khi không có tuyến đường rõ ràng nào khớp với yêu cầu đến.Mỗi phương thức HTTP ('GET', 'POST', v.v.) đều có trình xử lý mặc định riêng.
Nếu không có trình xử lý mặc định, các yêu cầu không khớp sẽ chống lại mạng như thể không có trình chạy dịch vụ nào.
Hàm
setDefaultHandler
có dạng như sau:(handler: RouteHandler, method?: HTTPMethod) => {...}
-
trình xử lý
Lệnh gọi lại hàm trả về Lời hứa dẫn đến Phản hồi.
-
method
HTTPMethod không bắt buộc
-
-
unregisterRoute
void
Huỷ đăng ký một tuyến đường với bộ định tuyến.
Hàm
unregisterRoute
có dạng như sau:(route: Route) => {...}
-
tuyến đường
Tuyến đường cần huỷ đăng ký.
-
Phương thức
registerRoute()
workbox-routing.registerRoute(
capture: string | RegExp | RouteMatchCallback | Route,
handler?: RouteHandler,
method?: HTTPMethod,
)
Dễ dàng đăng ký RegExp, chuỗi hoặc hàm bằng chức năng lưu vào bộ nhớ đệm cho thực thể bộ định tuyến singleton.
Phương thức này sẽ tạo một Tuyến đường cho bạn nếu cần và
gọi workbox-routing.Router#registerRoute
.
Tham số
-
chụp
string | RegExp | RouteMatchCallback | Tuyến đường
Nếu thông số thu thập là
Route
, mọi đối số khác sẽ bị bỏ qua. -
trình xử lý
RouteHandler không bắt buộc
-
method
HTTPMethod không bắt buộc
Giá trị trả về
-
Route
đã tạo.
setCatchHandler()
workbox-routing.setCatchHandler(
handler: RouteHandler,
)
Nếu Tuyến đường gửi lỗi trong khi xử lý yêu cầu, thì handler
này
sẽ được gọi và cho bạn cơ hội phản hồi.
Tham số
-
trình xử lý
Lệnh gọi lại hàm trả về Lời hứa dẫn đến Phản hồi.
setDefaultHandler()
workbox-routing.setDefaultHandler(
handler: RouteHandler,
)
Xác định handler
mặc định được gọi khi không có tuyến đường rõ ràng nào
khớp với yêu cầu đến.
Nếu không có trình xử lý mặc định, các yêu cầu không khớp sẽ chống lại mạng như thể không có trình chạy dịch vụ nào.
Tham số
-
trình xử lý
Lệnh gọi lại hàm trả về Lời hứa dẫn đến Phản hồi.