Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
438 views
in Technique[技术] by (71.8m points)

post - Response for preflight has invalid http status code 404 in my angular project while consuming web api

I know that it's CORS problem. I have enabled cors in web api server side. Get method is working fine but while dealing with post method I am facing problem . Please some one answer me with very simple post example both on web api and client side. With explanation of how to deal with preflight, options etc..

Console

1) zone.js:2935 OPTIONS http://localhost:49975/api/Add_Client_/postgoals 404 (Not Found)

2) Failed to load http://localhost:49975/api/Add_Client_/postgoals: Response for preflight has invalid HTTP status code 404.

web.config

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

    <add name="Access-Control-Allow-Credentials" value="true" />
  </customHeaders>
</httpProtocol>

Angular Post method

    save_Goals(){

  let headers : Headers= new Headers();
  //headers.append('Content-Type','application/x-www-form-urlencoded');
  //headers.append("Access-Control-Allow-Origin","true");
  headers.append('Content-Type', 'application/json');

  headers.append('Access-Control-Allow-Origin','*');
  headers.append('Access-Control-Allow-Methods','GET,PUT,POST,DELETE');
  headers.append('Access-Control-Allow-Headers','Content-Type');

  let options = new RequestOptions({ headers: headers });

    return this._http.post('http://localhost:49975/api/Add_Client_/postgoals', {goal:'foo'},options)
   .map(res =>  res.json());
  }

Thank you!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I am late but still wants to post the answer so to other it can be helpful. Below code works for me like a charm!

Here is the detailed answer to the question:

Pass data into the HTTP header from the Angular side (Please note I am using Angular4.0+ in the application).

There is more than one way we can pass data into the headers. The syntax is different but all means the same.

// Option 1 
 const httpOptions = {
   headers: new HttpHeaders({
     'Authorization': 'my-auth-token',
     'ID': emp.UserID,
   })
 };


// Option 2

let httpHeaders = new HttpHeaders();
httpHeaders = httpHeaders.append('Authorization', 'my-auth-token');
httpHeaders = httpHeaders.append('ID', '001');
httpHeaders.set('Content-Type', 'application/json');    

let options = {headers:httpHeaders};


// Option 1
   return this.http.post(this.url + 'testMethod', body,httpOptions)

// Option 2
   return this.http.post(this.url + 'testMethod', body,options)

In the call you can find the field passed as a header as shown in the image below : enter image description here

  1. Make changes at the backEnd/Web API side

Add new WebApiConfig file and add below content.

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.EnableCors(new EnableCorsAttribute("http://localhost:4200", headers: "ID", methods: "*") { SupportsCredentials = true }); // In the Header define all the header by comma cepration or you can write * if it works for you.
            /config.EnableCors(enableCorsAttribute);

            // Web API routes
            config.MapHttpAttributeRoutes();
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }

In the Global.asax.cs file add below event

protected void Application_BeginRequest()
        {
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers","ID");// In the Header define all the header by comma cepration or you can write * if it works for you.
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200");
                HttpContext.Current.Response.End();
            }
        }

And at the Web API side you can fetch that code with below statement :

 if (Request.Headers.Contains("ID"))
            {
                var ID= Request.Headers.GetValues("ID").First();
            }

you can follow these steps for below errors :

  • Response to preflight request doesn't pass access control check: No ''Access-Control-Allow-Origin'' header is present on the requested resource. Origin ''http://localhost:4200'' is therefore not allowed access

  • Response for preflight does not have HTTP ok status.

This code works for me, I am able to pass ID in the HTTP header and same I can retrieve at web API side.

Thanks and Happy coding!!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...