Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

serviceWorker removes Origin request header

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)));
}

enter image description here

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?

like image 746
William Lohan Avatar asked Jan 06 '18 01:01

William Lohan


People also ask

Does browser always send origin header?

The reason for that is, as mentioned earlier in this answer, browsers always send the Origin header in all POST , PUT , PATCH , and DELETE requests. Also, for completeness here and to be clear: For navigations, browsers send no Origin header.

Can we change Origin header of request?

In short: you cannot. As described on MDN; Origin is a 'forbidden' header, meaning that you cannot change it programatically. You would need to configure the web server to allow CORS requests.

What is Origin request header?

The Origin request header indicates the origin (scheme, hostname, and port) that caused the request. For example, if a user agent needs to request resources included in a page, or fetched by scripts that it executes, then the origin of the page may be included in the request.

Why is request origin null?

" Origin: “null” is an invalid origin, and then get rejected by the server framework." if Origin in absent of the header, the request pass. if Origin is set to “null”, the request is rejected.


1 Answers

Go to the server that is hosting your API, and make the following change on the CORS configuration.

Change the allowed origin from this:

<AllowedOrigin>*</AllowedOrigin>

TO

<AllowedOrigin>http://*</AllowedOrigin>
<AllowedOrigin>https://*</AllowedOrigin>
like image 132
Leon Grin Avatar answered Oct 09 '22 15:10

Leon Grin