I have a ASP.NET Web API 2 Service. And multiple client(angular) applications talks to that service. the applications and the service are published on different sub domains, like the following:
service.mydomain.com
app1.mydomain.com
app2.mydomain.com
I used Microsoft.AspNet.WebApi.Cors - NuGet package to enable CORS, it is working fine, except for one scenario: When the user opens one application (app1.mydomain.com). Then navigates to another (app2.mydomain.com). Then presses the browser back button. the follwoing CORS Error:
The 'Access-Control-Allow-Origin' header has a value 'http://app2.mydomain.com' that is not equal to the supplied origin.
Origin 'http://app1.mydomain.com' is therefore not allowed access
I Configured The Microsoft.AspNet.WebApi.Cors - NuGet package, as follows:
public static void Register(HttpConfiguration config)
{
var cors = new EnableCorsAttribute(
//to-do allow cross domains for all maarif.com sites
origins: "*", //and also tried "http://app1.mydomain.com, http://app2.mydomain.com" gives same result
headers: "*",
methods: "*") {SupportsCredentials = true};
config.EnableCors(cors);
}
I traced the Origin header values on the server. I put the following code in the service 'global.asax' :
protected void Application_BeginRequest()
{
var origin = HttpContext.Current.Request.Headers["Origin"];
if (origin != null )
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", origin);
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "*");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "*");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
}
}
The problem happens when user clicks back button form 'app2.mydomain.com' to 'app1.mydomain.com', the origin sent with the request is 'app2.mydomain.com', and there that is what the service allows access to: HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", 'app2.mydomain.com');
Any Way around this?
Note that I can't put '*' because the requests are authenticated.
The problem is due to the cache mechanism of browser. Because the browser would use the data from cache, even for AJAX request, when you clicked the BACK button.
For this, the browser wouldn't resend the CORS preflight to check the Access-Control-Allow-Origin
for the origin of previous page. Then it would use the latest Access-Control-Allow-Origin
, which is the app2.mydomain.com
, so that the app1.mydomain.com
should fail.
A simple solution is adding a timestamp or a random string at the end of the api querystring, for example:
let url = 'https://service.mydomain.com/xxxxx?v=' + Date.now();
However it would ignore Access-Control-Max-Age
, which makes a CORS preflight every request to the service.mydomain.com
.
Or you can force opening all links to other origin in a new window, so that there is no BACK actions could be done.
Except these, I can not find any other solutions.
Updated:
I tested later after this anwser, and then found the final solution:
Add following HTTP response headers in the service.mydomain.com
, and then all is ok.
Cache-Control: no-store,no-cache,must-revalidate
Pragma: no-cache
Just disable all cache of the AJAX requests. And the CORS Max-age works too.
Now it works in Chrome and Firefox. I didn't try other browsers, but I think it should be nothing different.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With