问题
The current behavior:
Service worker does not register due to the below error
The expected behavior:
Service worker registers
Details
Posted as a github issue: https://github.com/facebook/create-react-app/issues/8593
Service worker is giving the following error when attempting to register:
Error during service worker registration:
DOMException: Failed to register a ServiceWorker for scope ('http://localhost:3000/') with script ('http://localhost:3000/sw.js'):
The script has an unsupported MIME type ('text/html'). console. @ index.js:1
sw.js is showing in the sources tab of the Chrome dev tools, but not registering.
React version: 16.12.0
Error Message:
Error during service worker registration: DOMException:
Failed to register a ServiceWorker for scope ('http://localhost:3000/') with script ('http://localhost:3000/sw.js'):
The script has an unsupported MIME type ('text/html').
Failed ServiceWorker in Chrome's Inspect Tab:
Steps To Reproduce:
Register a Service Worker in React (change from unregister to register, or place SW code directly in index.html, or use a simpler SW. All cause the same error when running, in either dev or a build react app.)
SW Example:
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
);
});
}
}
Also, `http://localhost:3000/sw.js when using the default SW from React returns this HTML:
Using the code sample above returns index.html (default 404, http://localhost:3000/) when trying to access http://localhost:3000/sw.js
Suggested fixes:
Move sw.js to public folder, gives this error:
Is there a way to change the header (from text/html to application/javascript) for specifically sw.js when served to the browser in React?
I tried following some Medium articles on registering custom serviceWorkers in React, to no avail...
回答1:
When running webpack dev server, it renders default index.html for missing resource.
If you use your browser to load http://localhost:3000/sw.js, you will actually see a rendered react app (started by the index.html). That's why the mime type is html, not javascript.
This fallback to index.html is designed to support SPA with front-end routes. For example /product/123/reviews has no such html file in backend, the JS SPA app takes care of it in front-end.
Why your file is missing? I guess you created that file in the root folder of your project.
Webpack dev server doesn't serve from that root folder.
Move your sw.js into public/ folder of your project, it will be served up as expected.
回答2:
You can write code at server side to handle sw.js file. below is nodejs code which intercept sw.js file request and read from folder and send back to browser.
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
}
});
回答3:
This may be a duplicate of this one 61776698
Main think you need to know: Create the servieWorker inside public folder in order to be treated as .js file and not text/html file.
Then register that service in your index.js
Step 1, create public/sw.js
self.addEventListener('message', async (event) => {
console.log('Got message in the service worker', event);
});
Step 2, create 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');
});
});
}
}
Step 3, in src/index.js, add these two lines
import LocalServiceWorkerRegister from './sw-register';
...
LocalServiceWorkerRegister();
You can change some things for your needs, but with those changes, you should be able to work with a custom service worker in a create-react-app application
来源:https://stackoverflow.com/questions/60500779/serviceworker-mime-type-error-text-html-on-register-react