0

My server side is a C# mvc project.

We try to implement react to the client side.

I am using node-js with npm, using express server and hot-reloading, So when i compile my client-side code it runs on http://localhost:3000.

Now i want to add some server side calls. To do that I run my c# code using iis express which also opens on localhost in another port. Now the problem is that when the client code on port:3000 is making ajax calls to the iis express which is also on localhost i receive the "Response for preflight is invalid (redirect)" error, which is because of the same domain policy.

So what am i doing wrong, how are you suppose to work on dev mode when your server and client are seperated?

I tried to add to my ASP.NET

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

Edit - solution

When you send a post to a different domain, so first the client sends an OPTIONS request. So the solution is actually to add this code:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    EnableCrossOriginRequestsFromLocalhost(HttpContext.Current.Request);
}

private void EnableCrossOriginRequestsFromLocalhost(HttpRequest request)
{
    if (!HttpContext.Current.Request.IsLocal) return;
    if (request.UrlReferrer == null) return; //can't set Access-Control-Allow-Origin header reliably without a referrer so just return. Referrer should always be set when being called from an app under development because the app under development's URL will be sent as the referrer automatically.
    var response = HttpContext.Current.Response;
    response.AddHeader("Access-Control-Allow-Origin", request.UrlReferrer.GetLeftPart(UriPartial.Authority));
    response.AddHeader("Access-Control-Allow-Credentials", "true");
    if (request.HttpMethod == "OPTIONS")
    {
        response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE");
        response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
        response.AddHeader("Access-Control-Max-Age", "1728000");
        response.End();
    }
}
omriman12
  • 1,644
  • 7
  • 25
  • 48
  • You should allow CORS on your IIS express. `preflight` is HTTP OPTIONS request, in which the server should respond with `Allow-Control-*` headers. Here is a great introduction to CORS: http://www.html5rocks.com/en/tutorials/cors/ – zeronone Jul 12 '16 at 14:18
  • @zeronone I tried, look at my edit, it doesnt work, it worked on get requests, but not on post – omriman12 Jul 12 '16 at 14:24
  • Check this link: http://stackoverflow.com/questions/33645511/why-my-ajax-showing-preflight-is-invalid-redirect-error – zeronone Jul 12 '16 at 14:26
  • Obviously i looked at this post before, but again, its not solving it – omriman12 Jul 12 '16 at 14:27
  • Are you submitting a form, through POST request? Try setting the Content-Type to `application/x-www-form-urlencoded` – zeronone Jul 12 '16 at 14:28
  • You can additionally see the networks section on Chrome Dev Tools and check whether the `Allow-Control-*` headers are sent in the response. – zeronone Jul 12 '16 at 14:30
  • yes they are, still not working, used fiddler – omriman12 Jul 12 '16 at 14:54
  • @omriman12 if you used Fiddler, post what's shown there. – Lex Li Jul 12 '16 at 15:11
  • @omriman12 you might post that as an answer and accept it. Another approach is to use a generic HTTP handler which I documented on my personal blog. Preflight requests are special so without properly handling them the issue is quite common. – Lex Li Jul 13 '16 at 10:33

1 Answers1

1

In your case, the "React" part of the app all boils down to static resources: the initial html file that bootstraps the app, the .js bundle(s) with your React components and their dependencies, and any other static assets like .css file(s), images, that are referenced from the initial html file (via script tags, link tags, etc.).

The C# part of your app is then just concerned with dynamic requests, which amounts to api/ajax calls to get data that React will use to render the app in the browser.

I'm going to assume that you're using Webpack and the Webpack Dev Server. The simplest approach when developing is to have your Webpack Dev Server just proxy any api/ajax requests to the port where IISExpress is running. This is a simple setting in the Webpack.config.js file (see https://webpack.github.io/docs/webpack-dev-server.html#proxy). You use Webpack to create the bundles during build time, and then they're just served as static resources at runtime from the web server.

In Production, IIS serves everything (both static and dynamic requests) as well as probably authorizing access to the html resource that bootstraps your React app before serving it up, so there's no Express server involved.

domehead100
  • 161
  • 1
  • 7