设置 service worker 只排除某些 url
Setting service worker to exclude certain urls only
我使用 create react 构建了一个应用程序,默认情况下包含一个 service worker。我希望应用程序在有人输入给定的 url 时成为 运行,除非他们转到 /blog/,它提供一组静态内容。我在应用程序中使用反应路由器来捕获不同的 urls.
我有 nginx 设置来服务 /blog/ 如果有人访问 /blog/ 没有先访问反应应用程序,它工作正常。但是,因为 service worker 的作用域是 ./,任何时候有人访问除 /blog/ 之外的任何 url,应用程序都会加载 service worker。从那时起,service worker 绕过与服务器的连接并 /blog/ 加载反应应用程序而不是静态内容。
有没有办法让 Service Worker 在除 /blog/ 之外的所有 url 上加载?
因此,考虑到您还没有发布任何与 service worker 相关的代码,您可以考虑在 fetch
的代码块中添加一个简单的 if
条件
此代码块应该已经存在于您的服务中worker.Just添加条件
self.addEventListener( 'fetch', function ( event ) {
if ( event.request.url.match( '^.*(\/blog\/).*$' ) ) {
return false;
}
// OR
if ( event.request.url.indexOf( '/blog/' ) !== -1 ) {
return false;
}
// **** rest of your service worker code ****
注意您可以使用正则表达式或原型方法indexOf
。
随心所欲。
以上将指示您的服务人员,当 url 匹配 /blog/
时什么也不做
黑名单URL的另一种方法,即当您使用Workbox can be achieved with workbox.routing.registerNavigationRoute
时,将它们从缓存中排除:
workbox.routing.registerNavigationRoute("/index.html", {
blacklist: [/^\/api/,/^\/admin/],
});
上面的示例针对 SPA 演示了这一点,其中所有路由都被缓存并映射到 index.html
,但以 /api
或 [=14= 开头的任何 URL 除外].
尝试使用 sw-precache
library 覆盖当前 service-worker.js 文件,即 运行 缓存策略。最重要的部分是设置配置文件(我将在下面粘贴我与 create-react-app
一起使用的配置文件)。
- 安装
yarn sw-precache
- 创建并指定指示哪些 URL 不缓存的配置文件
- 修改构建脚本命令以确保
sw-precache
运行并覆盖构建输出目录中的默认service-worker.js
文件
我将我的配置文件命名为 sw-precache-config.js 并在 package.json[= 的构建脚本命令中指定了它33=]。该文件的内容如下。需要特别注意的部分是runtimeCachingkey/option。
"build": "NODE_ENV=development react-scripts build && sw-precache --config=sw-precache-config.js"
配置文件:sw-precache-config.js
module.exports = {
staticFileGlobs: [
'build/*.html',
'build/manifest.json',
'build/static/**/!(*map*)',
],
staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
swFilePath: './build/service-worker.js',
stripPrefix: 'build/',
runtimeCaching: [
{
urlPattern: /dont_cache_me1/,
handler: 'networkOnly'
}, {
urlPattern: /dont_cache_me2/,
handler: 'networkOnly'
}
]
}
以下是最新 CRA 版本中为我们工作的内容:
// serviceWorker.js
window.addEventListener('load', () => {
if (isAdminRoute()) {
console.info('unregistering service worker for admin route')
unregister()
console.info('reloading')
window.location.reload()
return false
}
我们从服务器工作者中排除 /admin
下的所有路由,因为我们为我们的管理区域使用了不同的应用程序。您当然可以根据自己的喜好更改它,这是我们在文件底部的功能:
function isAdminRoute() {
return window.location.pathname.startsWith('/admin')
}
如果你正在使用或愿意使用customize-cra,解决方案相当straight-forward。
将此放入您的 config-overrides.js
:
const { adjustWorkbox, override } = require("customize-cra");
module.exports = override(
adjustWorkbox(wb =>
Object.assign(wb, {
navigateFallbackWhitelist: [
...(wb.navigateFallbackWhitelist || []),
/^\/blog(\/.*)?/,
],
})
)
);
请注意,在最新的 workbox documentation 中,该选项称为 navigateFallbackAllowlist 而不是 navigateFallbackWhitelist。因此,根据您使用的 CRA/workbox 版本,您可能需要更改选项名称。
正则表达式 /^/blog(/.*)?/ 匹配 /blog、/blog/、/blog/abc123 等
以下是您在 2021 年的做法:
import {NavigationRoute, registerRoute} from 'workbox-routing';
const navigationRoute = new NavigationRoute(handler, {
allowlist: [
new RegExp('/blog/'),
],
denylist: [
new RegExp('/blog/restricted/'),
],
});
registerRoute(navigationRoute);
更新(新的工作解决方案)
在 Create React App 的最后一个主要版本(版本 4.x.x)中,您可以轻松实现您的自定义 worker-service.js 而无需流血。 customize worker-service
Starting with Create React App 4, you have full control over customizing the logic in this service worker, by creating your own src/service-worker.js file, or customizing the one added by the cra-template-pwa (or cra-template-pwa-typescript) template. You can use additional modules from the Workbox project, add in a push notification library, or remove some of the default caching logic.
如果您当前使用的是旧版本,则必须将您的 React 脚本升级到版本 4。
CRA v4 的工作解决方案
在registerRoute
-method.
中的匿名函数内将以下代码添加到文件service-worker.js
中
// If this is a backend URL, skip
if (url.pathname.startsWith("/backend")) {
return false;
}
为了简化事情,我们可以添加要排除的项目的数组列表,并在获取事件侦听器中添加搜索。
为了完整起见,下面包含和排除方法。
var offlineInclude = [
'', // index.html
'sitecss.css',
'js/sitejs.js'
];
var offlineExclude = [
'/networkimages/bigimg.png', //exclude a file
'/networkimages/smallimg.png',
'/admin/' //exclude a directory
];
self.addEventListener("install", function(event) {
console.log('WORKER: install event in progress.');
event.waitUntil(
caches
.open(version + 'fundamentals')
.then(function(cache) {
return cache.addAll(offlineInclude);
})
.then(function() {
console.log('WORKER: install completed');
})
);
});
self.addEventListener("fetch", function(event) {
console.log('WORKER: fetch event in progress.');
if (event.request.method !== 'GET') {
console.log('WORKER: fetch event ignored.', event.request.method, event.request.url);
return;
}
for (let i = 0; i < offlineExclude.length; i++)
{
if (event.request.url.indexOf(offlineExclude[i]) !== -1)
{
console.log('WORKER: fetch event ignored. URL in exclude list.', event.request.url);
return false;
}
}
我使用 create react 构建了一个应用程序,默认情况下包含一个 service worker。我希望应用程序在有人输入给定的 url 时成为 运行,除非他们转到 /blog/,它提供一组静态内容。我在应用程序中使用反应路由器来捕获不同的 urls.
我有 nginx 设置来服务 /blog/ 如果有人访问 /blog/ 没有先访问反应应用程序,它工作正常。但是,因为 service worker 的作用域是 ./,任何时候有人访问除 /blog/ 之外的任何 url,应用程序都会加载 service worker。从那时起,service worker 绕过与服务器的连接并 /blog/ 加载反应应用程序而不是静态内容。
有没有办法让 Service Worker 在除 /blog/ 之外的所有 url 上加载?
因此,考虑到您还没有发布任何与 service worker 相关的代码,您可以考虑在 fetch
if
条件
此代码块应该已经存在于您的服务中worker.Just添加条件
self.addEventListener( 'fetch', function ( event ) {
if ( event.request.url.match( '^.*(\/blog\/).*$' ) ) {
return false;
}
// OR
if ( event.request.url.indexOf( '/blog/' ) !== -1 ) {
return false;
}
// **** rest of your service worker code ****
注意您可以使用正则表达式或原型方法indexOf
。
随心所欲。
以上将指示您的服务人员,当 url 匹配 /blog/
黑名单URL的另一种方法,即当您使用Workbox can be achieved with workbox.routing.registerNavigationRoute
时,将它们从缓存中排除:
workbox.routing.registerNavigationRoute("/index.html", {
blacklist: [/^\/api/,/^\/admin/],
});
上面的示例针对 SPA 演示了这一点,其中所有路由都被缓存并映射到 index.html
,但以 /api
或 [=14= 开头的任何 URL 除外].
尝试使用 sw-precache
library 覆盖当前 service-worker.js 文件,即 运行 缓存策略。最重要的部分是设置配置文件(我将在下面粘贴我与 create-react-app
一起使用的配置文件)。
- 安装
yarn sw-precache
- 创建并指定指示哪些 URL 不缓存的配置文件
- 修改构建脚本命令以确保
sw-precache
运行并覆盖构建输出目录中的默认service-worker.js
文件
我将我的配置文件命名为 sw-precache-config.js 并在 package.json[= 的构建脚本命令中指定了它33=]。该文件的内容如下。需要特别注意的部分是runtimeCachingkey/option。
"build": "NODE_ENV=development react-scripts build && sw-precache --config=sw-precache-config.js"
配置文件:sw-precache-config.js
module.exports = {
staticFileGlobs: [
'build/*.html',
'build/manifest.json',
'build/static/**/!(*map*)',
],
staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
swFilePath: './build/service-worker.js',
stripPrefix: 'build/',
runtimeCaching: [
{
urlPattern: /dont_cache_me1/,
handler: 'networkOnly'
}, {
urlPattern: /dont_cache_me2/,
handler: 'networkOnly'
}
]
}
以下是最新 CRA 版本中为我们工作的内容:
// serviceWorker.js
window.addEventListener('load', () => {
if (isAdminRoute()) {
console.info('unregistering service worker for admin route')
unregister()
console.info('reloading')
window.location.reload()
return false
}
我们从服务器工作者中排除 /admin
下的所有路由,因为我们为我们的管理区域使用了不同的应用程序。您当然可以根据自己的喜好更改它,这是我们在文件底部的功能:
function isAdminRoute() {
return window.location.pathname.startsWith('/admin')
}
如果你正在使用或愿意使用customize-cra,解决方案相当straight-forward。
将此放入您的 config-overrides.js
:
const { adjustWorkbox, override } = require("customize-cra");
module.exports = override(
adjustWorkbox(wb =>
Object.assign(wb, {
navigateFallbackWhitelist: [
...(wb.navigateFallbackWhitelist || []),
/^\/blog(\/.*)?/,
],
})
)
);
请注意,在最新的 workbox documentation 中,该选项称为 navigateFallbackAllowlist 而不是 navigateFallbackWhitelist。因此,根据您使用的 CRA/workbox 版本,您可能需要更改选项名称。
正则表达式 /^/blog(/.*)?/ 匹配 /blog、/blog/、/blog/abc123 等
以下是您在 2021 年的做法:
import {NavigationRoute, registerRoute} from 'workbox-routing';
const navigationRoute = new NavigationRoute(handler, {
allowlist: [
new RegExp('/blog/'),
],
denylist: [
new RegExp('/blog/restricted/'),
],
});
registerRoute(navigationRoute);
更新(新的工作解决方案) 在 Create React App 的最后一个主要版本(版本 4.x.x)中,您可以轻松实现您的自定义 worker-service.js 而无需流血。 customize worker-service
Starting with Create React App 4, you have full control over customizing the logic in this service worker, by creating your own src/service-worker.js file, or customizing the one added by the cra-template-pwa (or cra-template-pwa-typescript) template. You can use additional modules from the Workbox project, add in a push notification library, or remove some of the default caching logic.
如果您当前使用的是旧版本,则必须将您的 React 脚本升级到版本 4。
CRA v4 的工作解决方案
在registerRoute
-method.
service-worker.js
中
// If this is a backend URL, skip
if (url.pathname.startsWith("/backend")) {
return false;
}
为了简化事情,我们可以添加要排除的项目的数组列表,并在获取事件侦听器中添加搜索。
为了完整起见,下面包含和排除方法。
var offlineInclude = [
'', // index.html
'sitecss.css',
'js/sitejs.js'
];
var offlineExclude = [
'/networkimages/bigimg.png', //exclude a file
'/networkimages/smallimg.png',
'/admin/' //exclude a directory
];
self.addEventListener("install", function(event) {
console.log('WORKER: install event in progress.');
event.waitUntil(
caches
.open(version + 'fundamentals')
.then(function(cache) {
return cache.addAll(offlineInclude);
})
.then(function() {
console.log('WORKER: install completed');
})
);
});
self.addEventListener("fetch", function(event) {
console.log('WORKER: fetch event in progress.');
if (event.request.method !== 'GET') {
console.log('WORKER: fetch event ignored.', event.request.method, event.request.url);
return;
}
for (let i = 0; i < offlineExclude.length; i++)
{
if (event.request.url.indexOf(offlineExclude[i]) !== -1)
{
console.log('WORKER: fetch event ignored. URL in exclude list.', event.request.url);
return false;
}
}