I have an angular app and as soon as I add a serviceWorker following these steps:
https://github.com/angular/angular-cli/blob/master/docs/documentation/build.md#service-worker https://angular.io/guide/service-worker-getting-started
…my API requests no longer have an Origin
request header, which seems to cause my API server to not return an Access-Control-Allow-Origin
response header, causing a browser error:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Simply removing the serviceWorker and unregistering it returns the behavior to normal.
How do I implement a serviceWorker while continuing to use my restful API?
All of the requests are affected but some are made "under the hood" by oidc-client
; all of the others look like:
public getBook(bookId: number): Observable<Book> {
const request = new HttpRequest(
'get',
`https://some-server.asurewebsites.net/api/book/${bookId}`,
{
reportProgress: true,
responseType: 'json'
}
);
return this.httpClient.request<any>(request).do(event => {
this.progressService.processEvent(event);
}).filter(event => event instanceof HttpResponse)
.map((response: HttpResponse<any>) => deserializeBook(response.body)).catch(error => {
if (error instanceof HttpErrorResponse) {
if (error.status === 404) {
return Observable.of(null);
}
}
return Observable.throw(error);
});
}
// note: other constraints require listening to progress from per-request level rather than using a HttpIntercepter.
Update1:
Manually setting Origin
I get:
Refused to set unsafe header "Origin"
Manually setting Access-Control-Allow-Origin
does nothing because it is a response header.
The Fetch API has a Request.mode
that when set to 'cors'
will send an OPTIONS
request with a Origin
header like normal. I'd try explicitly setting that but I'm having trouble researching or find the in the documentation how to set that with angular HttpClient
Update2:
I tried converting one of the requests to use the Fetch API. So I set Request.mode
to 'cors'
, but I still get no Origin
request header and no Access-Control-Allow-Origin
response header.
public getBookList(): Observable<BookList[]> {
const fetchHeaders = new Headers();
fetchHeaders.set('Authorization', 'Bearer ${token}');
const fetchRequest = new Request(`https://some-server.asurewebsites.net/api/book`, {
method: 'get',
headers: fetchHeaders,
mode: 'cors'
});
return Observable.fromPromise(fetch(fetchRequest).then(response => response.json()))
.map((results: any[]) => results.map(entity => deserializeBook(entity)));
}
TLDR
Once a service worker is registered the browser no longer uses CORS, even if mode: 'cors'
is explicitly set by the client. How do I use a service worker and CORS?