1

I'm using Angular 9. I have these requests to get binary image data ...

headersMultiPartForm = new HttpHeaders().set('Content-Type', 'multipart/form-data');
    ...
  getImage(id) {
    let api = `${this.endpoint}/person-library-image?id=${id}`;
    return this.http
      .get(api, {headers: this.headersMultiPartForm, responseType: "blob"})
      .pipe(retry(this.retry), catchError(this.handleError));
  }

    ...
results.forEach(( componentarray, key ) => {
    ...
    this.myService.getImage(id).subscribe(data => {
      ...
      this.createImageFromBlob(data, index);
      ...
    }, () => {
      ...
    });

});

I'm noticing that the requests are taking a while to complete and it seems it is because they are being blocked waiting for OPTIONS requests to complete. I would like to prevent these preflight OPTIONS requests from being sent. I thought that my "multipart/form-data" would prevent the preflight request, but apparently not ...

enter image description here

When I examine the actual request by right-clicking and copying as CURL I see ...

curl 'http://localhost:7071/api/person-library-image?id=127' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:81.0) Gecko/20100101 Firefox/81.0' -H 'Accept: application/json, text/plain, */*' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Referer: http://localhost:4200/picture-library' -H 'Content-Type: multipart/form-data' -H 'Authorization: JWT <token>' -H 'Origin: http://localhost:4200' -H 'Connection: keep-alive' -H 'Pragma: no-cache' -H 'Cache-Control: no-cache'

I have an interceptor adding the Authorization header, but I don't know where the other headers are coming from. Any ideas how I turn them off so I can prevent these preflight OPTIONS requests?

Dave
  • 17,420
  • 96
  • 300
  • 582
  • Does this answer your question? [Why is an OPTIONS request sent and can I disable it?](https://stackoverflow.com/questions/29954037/why-is-an-options-request-sent-and-can-i-disable-it) – R. Richards Nov 13 '20 at 16:00
  • I tried adding an additional "Access-Control-Max-Age: 600" header as it recommended but the OPTIONS requests continue to be sent. – Dave Nov 13 '20 at 16:19
  • `Content-Type: multipart/form-data` *should* be a [simple request](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests), not requiring a preflight; does your request have anything else (e.g. added by an interceptor) that pushes it out of that category? – jonrsharpe Nov 13 '20 at 17:30

1 Answers1

0

What you are talking about is Simple vs Non-simple CORS requests.

Indeed POST with application/x-www-form-urlencoded Content-Type is simple as stated in post so should not require preflight. But, there is one important note which is your case:

☝ Another tricky important condition - to be simple requests must have no manually 
set headers. Default headers sent by browser are OK, we are talking only about 
headers set by you from your request maker like XHR/fetch/axios/superagent/jQuery Ajax. 
BTW request maker can set it without your agreement, so better start with pure 
browser-native XHR of fetch API, don't use superagent/axios unless you know why
you need it. If you need to set a header by yourself still  and still want keep 
request simple you are allowed to white-listed request headers and their values, they
called CORS-safelisted. You can find their list and allowed values on fetch spec: 
https://fetch.spec.whatwg.org/#cors-safelisted-request-header

Check headers in request, probably you have some interceptor which adds it, with big probability they are not CORS-safelisted according to https://fetch.spec.whatwg.org/#cors-safelisted-request-header

Ivan Borshchov
  • 2,215
  • 3
  • 26
  • 56