注册时的 ServiceWorker MIME 类型错误('text/html')(React)
Posted
技术标签:
【中文标题】注册时的 ServiceWorker MIME 类型错误(\'text/html\')(React)【英文标题】:ServiceWorker MIME Type Error ('text/html') on register (React)注册时的 ServiceWorker MIME 类型错误('text/html')(React) 【发布时间】:2020-06-15 10:53:01 【问题描述】:当前行为:
由于以下错误,Service Worker 未注册
预期行为:
Service Worker 注册
详情
作为 github 问题发布: https://github.com/facebook/create-react-app/issues/8593
Service Worker 在尝试注册时出现以下错误:
Service Worker 注册时出错: DOMException: 无法使用脚本 ('http://localhost:3000/sw.js') 为范围 ('http://localhost:3000/') 注册 ServiceWorker: 该脚本具有不受支持的 MIME 类型 ('text/html')。 安慰。 @index.js:1
sw.js
显示在 Chrome 开发工具的源选项卡中,但未注册。
反应版本:16.12.0
错误信息:
Service Worker 注册期间出错:DOMException: 使用脚本 ('http://localhost:3000/sw.js') 为范围 ('http://localhost:3000/') 注册 ServiceWorker 失败: 该脚本具有不受支持的 MIME 类型('text/html')。
Chrome 的检查选项卡中的 ServiceWorker 失败:
复制步骤:
在 React 中注册一个 Service Worker(从取消注册更改为注册,或者将 SW 代码直接放在 index.html 中,或者使用更简单的 SW。在开发或构建 react 应用程序中运行时都会导致相同的错误。)
软件示例:
export function register()
if ("serviceWorker" in navigator)
navigator.serviceWorker
.register("./sw.js")
.then(function(registration)
// Successful registration
console.log(
"Hooray. Registration successful, scope is:",
registration.scope
);
)
.catch(function(error)
// Failed registration, service worker won’t be installed
console.log(
"Whoops. Service worker registration failed, error:",
error
);
);
此外,`http://localhost:3000/sw.js 在使用 React 的默认 SW 时会返回此 HTML:
使用上面的代码示例在尝试访问http://localhost:3000/sw.js 时返回 index.html(默认 404,http://localhost:3000/)
建议的修复:
将sw.js
移动到公用文件夹,出现此错误:
当在 React 中提供给浏览器时,有没有办法将标头(从 text/html
更改为 application/javascript
)专门用于 sw.js
?
我尝试关注一些关于在 React 中注册自定义 serviceWorkers 的 Medium 文章,但无济于事......
【问题讨论】:
sw.js
的服务怎么样?
使用 React 中的 serviceWorker.register()。
我在你的网络服务器上说
我只是在使用基本的 npm start,无论哪个用于 React 的默认值。目前正在开发中,因此尚未部署。我也做过npm build,然后serve -s build 为构建好的项目服务,但还是报同样的错误。
建议的解决方法 - 将生产版本部署到本地静态服务器:npm run build && npx serve -s build
【参考方案1】:
在运行 webpack 开发服务器时,它会为缺少的资源呈现默认 index.html。
如果您使用浏览器加载http://localhost:3000/sw.js
,您实际上会看到一个渲染的 React 应用程序(由 index.html 启动)。这就是为什么 mime 类型是 html,而不是 javascript。
这个 index.html 的后备方案旨在支持带有前端路由的 SPA。例如/product/123/reviews
在后端没有这样的html文件,JS SPA应用程序在前端处理它。
为什么您的文件丢失了?我猜你在项目的根文件夹中创建了该文件。
Webpack 开发服务器不从该根文件夹提供服务。
将您的sw.js
移动到项目的public/
文件夹中,它将按预期提供。
【讨论】:
最好将.register("./sw.js")
更改为.register("/sw.js")
以避开当前路线。
http://localhost:3000/sw.js
以 html 中包裹的代码响应,放置 sw.js 会返回错误 ERRORS: Example localhost/sw.js: imgur.com/a/EjKg8RJ ||公开发布错误:imgur.com/a/xdf772U
sw.js 与 create-react-app 捆绑的默认 serviceWorker.js 文件位于同一位置
将 './sw.js'
更改为 /sw.js
会出现此错误:找不到模块:您尝试导入项目 src/ 目录之外的 /sw。不支持 src/ 之外的相对导入。
更新:改回上述 SW 的代码示例,返回 index.html。但是,移动到公用文件夹会返回如上的错误。【参考方案2】:
这可能是这个61776698的副本
你需要知道的主要事情:在公共文件夹中创建 serviceWorker 以便被视为 .js 文件而不是 text/html 文件。
然后在 index.js 中注册该服务
第一步,创建public/sw.js
self.addEventListener('message', async (event) =>
console.log('Got message in the service worker', event);
);
第二步,创建src/sw-register.js
export default function LocalServiceWorkerRegister()
const swPath = `$process.env.PUBLIC_URL/sw-build.js`;
if ('serviceWorker' in navigator && process.env.NODE_ENV !== 'production')
window.addEventListener('load', function ()
navigator.serviceWorker.register(swPath).then(registration =>
console.log('Service worker registered');
);
);
第三步,在src/index.js中,添加这两行
import LocalServiceWorkerRegister from './sw-register';
...
LocalServiceWorkerRegister();
您可以根据需要更改一些内容,但是通过这些更改,您应该能够在 create-react-app 应用程序中使用自定义服务工作者
【讨论】:
路径与文件名不同 (sw-build.js
/ sw.js
)。这是故意的吗?【参考方案3】:
您可以在服务器端编写代码来处理 sw.js 文件。下面是拦截 sw.js 文件请求并从文件夹中读取并发送回浏览器的 nodejs 代码。
app.get('/sw.js', (req, res) =>
if (__DEVELOPMENT__)
http.get('http://localhost:4001/static/build/sw.js', (r) =>
res.set(
'Content-Type': 'text/javascript',
'Cache-Control': 'max-age=0, no-cache, no-store, must-revalidate'
);
r.setEncoding('utf8');
r.pipe(res);
).on('error', (e) =>
console.error(`Error in sending sw.js in dev mode : $e.message`);
);
else
res.setHeader('Cache-Control', 'max-age=0, no-cache, no-store, must-revalidate');
res.sendFile('sw.js', root: path.join(__ROOT_DIRECTORY__, 'assets', 'build') ); // eslint-disable-line no-undef
);
【讨论】:
以上是关于注册时的 ServiceWorker MIME 类型错误('text/html')(React)的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 无法使用脚本为范围注册 ServiceWorker,该脚本具有不受支持的 MIME 类型
FirebaseError browserErrorMessage:“无法注册 ServiceWorker:ServiceWorker 脚本评估失败”
注册 ServiceWorker 返回 AbortError code:20
在浏览器中出现错误 - 无法为范围注册 ServiceWorker
将 Firebase FCM 添加到 reactjs 应用程序
“未捕获(承诺)的DOMException:无法为范围注册ServiceWorker”-脚本资源位于重定向后面,不允许使用