3

I've spent several days trying to identify why my CORS applications suddenly began to fail in Chrome when I updated from Chrome v36.xxx to v37.yyy (specifically 37.0.2062.103 ) In my application I run an MVC site and a WebAPI on a different port. This is where the cross-domain comes into things.

I've got several instance (dev, uat, prod) all acting the same way. All used to work.

XMLHttpRequest cannot load http://"mywebapihost":"mywebapiport"/api/v1.0/myapp/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://"mymvchost"' is therefore not allowed access.

Seems to be a problem with the OPTIONS request in the Preflight - which I've seen mentioned a lot on the web.

However - I don't feel any closer to "fixing" my problem (where "fixing" == being able to run in Chrome).

Things I can state about my system :

(1) Has always worked with v36.xxx, but not since 37.0.2062.103 update (2) Works in IE (3) Works for GETs even in latest Chrome (4) Works, even in latest Chrome. if I have Fiddler running (I don't count this as a fix!)

What I've tried.

1) Forcing headers in the calling jQuery Ajax call to try to get the authorization into the OPTIONS call - suggestions from the web

beforeSend: function (xhr) {
   xhr.setRequestHeader('Authorization', make_base_auth("<username>", "<password>"));
},
headers: {
   "Authorization": "Basic " + btoa("<username>" + ":" + "<password>")
}

2) I downloaded Chrome Canary v39.0.2150.3 in the hope that this issue would be gone - still get same failures.

If anyone has any suggestions I would be very grateful, I've have to change to running IE just to make progress!

talves
  • 13,993
  • 5
  • 40
  • 63
chrisward
  • 45
  • 8
  • The Origin reported is clearly wrong. Are you running this as a test from your local machine? – Rhys Sep 10 '14 at 12:52
  • Edit made. I'd put in placeholders for the mvc host, webapi host and webapi port in but, because I put them inside "<" and ">" they failed to show up in the post. BTW - the mvc host and web api host are the same. Only the port is different, which still classes as "cross domain" apparently. – chrisward Sep 10 '14 at 13:49
  • Can you debug the server to see why it isn't attaching the Access-Control-Allow-Origin header? – Rhys Sep 10 '14 at 15:22
  • @Ryven : I do have full access to the server(s) yes. This is running on IIS (I am historically more of a Java/Tomcat guy) but I do have access to all the config and log files. Things is, if I make an explicit OPTIONS Request using a tool such as "Postman" (Chrome plugin) it DOES get through. The thing that fails, and I now see it's not just Chrome but also Firefox, is the automatically generated OPTIONS Preflight for a POST or PATCH Request using jQuery Ajax(). I think it just showed up through Chrome because the update made it stricter. – chrisward Sep 12 '14 at 07:13

2 Answers2

0

For the sake of closure I am answering my own question here. It might help someone in the future.

What I did was to create a totally clean, minimal working WebAPI project which implemented GET, PUT, POST and DELETE. I got this working as expected then tried it cross-domain (same server but webpage running JS Ajax was on port 80 and the WebAPI was running on port 7694).

This predictably failed. So then I enabled CORS with the required nuget package, added the

        config.EnableCors();

in WebApiConfigcs.

In my minimal WebAPI Controller I added the

[EnableCors(origins: "*", headers: "*", methods: "*", SupportsCredentials = true)]

All this worked as intended.

However, when I then installed the same Controller etc into my existing, failing WebAPI deployment it failed in the way that prompted my original question.

So it had the smell of config about it.

It turned out to be fixed by cleansing the configuration of both my IIS Server and the WebAPI project I was deploying. I had poked around too much with both when trying to make the pre-flight OPTIONS request to work.

Specificall, in Web.Config I had added

  <system.web>
    ....
    ....
    <!--<authentication mode="Windows" />-->
    <authorization>
      <deny users="?" />
      <allow verbs="OPTIONS" users="?" />
    </authorization>
  </system.web>

And

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE" />
    <add name="Access-Control-Allow-Headers" value="Content-Type" />
  </customHeaders>
</httpProtocol>

When following suggestions seen on the Web.

I removed both of these and things started to work.

I appreciate this is a bit of a fuzzy answer but it may save someone the frustration I had for days.

Chris

chrisward
  • 45
  • 8
0

I'm having the same problem. I've just updated to Chrome 38 (38.0.2125.101 m) and the problem persists. As suggested below, I've deleted my answer here and created a new question: Chrome v37/38 CORS failing (again) with 401 for OPTIONS pre-flight requests.

As you will see in that question, my Angular app is sending an explicit withCredentials, so the server should authenticate the pre-flighted OPTIONS request correctly.

Community
  • 1
  • 1
Cornel Masson
  • 1,352
  • 2
  • 17
  • 33
  • Your request is missing the `Authorization` request header. Have you set `xhr.withCredentials = true`? Could you delete this "answer" and post a new question that contains the request headers and response headers of the OPTIONS request and the final response? – Rob W Oct 09 '14 at 08:42
  • Rob, please see my newly added question (link above) – Cornel Masson Oct 10 '14 at 10:04