How to solve IE/Edge CORS error ?

As a web developer, it is highly likely that you have encountered below while trying to fetch data from other domain.

XMLHTTPrequest cannot load <api_name>. No 'Acess-Control-Allow-Origin' header is present on the requested resource. Origin <your_website> is therefore not allowed to access

But, ever encountered a scenario where it is working fine on every other browser on the planet but not on Internet Explorer or Edge.

This can be a little frustrating.

Below is a sample request and response headers of the preflight request in Chrome and IE.

Origin site is https://mydomain.com and requested resource is on https://externaldomain.com

Chrome

Request URL: https://externaldomain.com/user Request Method:OPTIONS Status Code:200 OK

Request Headers

Accept:*/* Accept-Encoding:gzip, deflate, sdch, br Accept-Language:en-US,en;q=0.8 Access-Control-Request-Headers:content-type Access-Control-Request-Method:POST Connection:keep-alive Host:xyz.mydomain.com Origin:https://mydomain.com Referer:https://mydomain.com User-Agent:Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36

Response Headers

Access-Control-Allow-Credentials:true Access-Control-Allow-Headers:* Access-Control-Allow-Headers:Origin, X-Requested-With, Content-Type, token, phonenumber, ssoid, Accept Access-Control-Allow-Methods:POST, GET, OPTIONS, PUT, DELETE Access-Control-Allow-Origin:https://mydomain.com Allow:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH Content-Length:0 Date:Tue, 11 Oct 2016 11:39:14 GMT Server:Apache-Coyote/1.1 Set-Cookie:LB=check; path=/

IE 11

Request Headers

Request OPTIONS https://externaldomain.com/user HTTP/1.1 Accept */* Origin https://mydomian.com Access-Control-Request-Method POST Access-Control-Request-Headers accept, content-type Accept-Encoding gzip, deflate User-Agent Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko Host https://externaldomain.com Content-Length 0 DNT 1 Connection Keep-Alive Cache-Control no-cache

Response Headers

Response HTTP/1.1 200 OK Server Apache-Coyote/1.1 Allow GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH Content-Length 0 Date Tue, 11 Oct 2016 11:55:50 GMT Access-Control-Allow-Headers * Access-Control-Allow-Credentials true Access-Control-Allow-Origin https://mydomain.com Access-Control-Allow-Methods POST, GET, OPTIONS, PUT, DELETE Access-Control-Allow-Headers Origin, X-Requested-With, Content-Type, token, phonenumber, ssoid, Accept Set-Cookie LB=check; path=/

In chrome this works completely fine, however in IE, below warning and error are thrown.

SEC7118: XMLHttpRequest for https://externaldomain.com/user required Cross Origin Resource Sharing (CORS).

SEC7119: XMLHttpRequest for https://externaldomain.com/user required CORS preflight

SEC7123: Request header content-type was not present in the Access-Control-Allow-Headers list.

SCRIPT7002: XMLHttpRequest: Network Error 0x80070005, Access is denied.

This error doesn’t make much sense as the preflight call has been called and it returned with 200 OK. content-type is also part of the allowed headers in response so no point there (until and unless case sensitivity is there).

Now how to resolve it, and I say, why not bypass it.

The way we can bypass it is, rather calling the API from your browser to the other domain, call your own domain API (for example /api) and at nginx level proxy it to the destination server.

In nginx (or any other web server) create proxy pass like below

location ~ ^/api/(?<section>.*) { resolver 8.8.8.8; proxy_pass https://externaldomain.com/$section$is_args$args; }

And in your client frontend script you need to write something like this

if (isBrowserIE || isBrowserEdge) { url = '/api/user'; } else { url = 'https://externalmydomain.com/user'; }

So when on IE or Edge, calls will go to your own domain otherwise directly to external domain.

Above strategy is the easiest way of handling CORS issue on IE/Edge, although there must be other solutions, do check them out and let me know if they help.


Originally published at syedhaani.com on October 12, 2016.