lukejacksonn / servor

Dependency free file server for single page app development
MIT License
1.04k stars 70 forks source link

cors issues with localhost:5000 and service worker #30

Closed zaceno closed 5 years ago

zaceno commented 5 years ago

Hi Luke,

This might not at all be an issue relevant to servør, but rather my total noobesse wrt service-workers. Just now starting to toy with service workers and made a real simple one:

const CACHE_NAME = 'cache'
self.addEventListener('install', event => {
    caches.open(CACHE_NAME).then(cache => cache.addAll(['/index.html', '/index.js']))
})

self.addEventListener('fetch', function(event) {
    event.respondWith(
        caches.match(event.request).then(function(response) {
            return response || fetch(event.request).then((response = {}))
        })
    )
})

When my index.html contains code for registering this service worker, servor starts up fine. But if I either reload once manually, or if I make a change to a file (to trigger a reload via the eventsource), I start getting these errors plopping out in my console:

Access to fetch at 'http://localhost:5000/' from origin 'http://localhost:8080' has been blocked by CORS policy: Request header field cache-control is not allowed by Access-Control-Allow-Headers in preflight response.
service-worker.js:1
Uncaught (in promise) TypeError: Failed to fetch
:5000/:1
GET http://localhost:5000/ net::ERR_FAILED

Somehow it seems when the service worker is intercepting the event source, it gets angry about cors headers.

Again, I'm just too much of a beginner to know wether this is something to fix in servor or with my service worker. Do you know?

zaceno commented 5 years ago

Ok I figured it out. Not exactly sure what the issue is, but I can fix it in my service worker by hardcoding an exception:

self.addEventListener('fetch', function(event) {
    if (event.request.url === 'http://localhost:5000/') return
    event.respondWith(
        caches.match(event.request).then(function(response) {
            return response || fetch(event.request).then((response = {}))
        })
    )
})

Pardon the bother ;)

lukejacksonn commented 5 years ago

Yo 👋 no worries, glad you got it sorted! I haven't played around with service workers too much but I did manage to get one working with servor the other day.. there is also this issue https://github.com/lukejacksonn/servor/issues/25.

zaceno commented 5 years ago

👍 Apparently service-workers require Access-Control-Allow-Origin headers for any requests they make (whereas simply adding a cross-origin script tag to the page does not). And since I was passing all my requests through the service worker (to make sure we use the cache for offline), that's why I got the error.

Since I don't care about caching the request to localhost:500 my solution seems ok. There is also a workaround for resources you do want cached, apparently (by sending the request with {mode: 'no-cors'}) but it too has some caveats.

TL;DR: Service workers are hard...