使用 Web api 时,我的 angular 项目中的预检响应具有无效的 http 状态代码 404

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

我知道这是 CORS 问题。我在 web api 服务器端启用了 cors。 Get 方法工作正常,但在处理 post 方法时我遇到了问题。请有人在网络 api 和客户端用非常简单的 post 示例回答我。解释如何处理预检、选项等。

控制台

1) zone.js:2935 选项 http://localhost:49975/api/Add_Client_/postgoals 404(未找到)

2) 加载失败 http://localhost:49975/api/Add_Client_/postgoals:预检响应具有无效的 HTTP 状态代码 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>

AngularPost方法

    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());
  }

谢谢!

我终于找到了解决办法。我所做的是从 web.config 文件中删除自定义 headers。即,

<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>

此内容我已删除

WebApiConfig.cs 中,我做了以下更改

var enableCorsAttribute = new EnableCorsAttribute(origins:"*",headers:"*",methods:"*");

            var json = config.Formatters.JsonFormatter;

            json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
            config.Formatters.Remove(config.Formatters.XmlFormatter);

            config.EnableCors(enableCorsAttribute);

控制器看起来像这样。

[EnableCors(origins: "*", headers: "*", methods: "*", SupportsCredentials = true)]
    [RoutePrefix("api/Add_Client_")]
    public class Add_Client_Controller : ApiController
    {
[AcceptVerbs("POST")]

        [HttpPost]
        [Route("PostGoals")]
        public string PostGoals(string goal)
        {
            Goal g = new Goal();
            g.Goals = goal;
            db.Goals.Add(g);
            int res = db.SaveChanges();

            return ("Success");
        }
}

Angular POST 方法如下

 save_Goals(){

  let headers : Headers= new Headers();
        headers.append('Content-Type','application/x-www-form-urlencoded');
    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=check',options)
       .map(res =>  res.json());
    }

这是使用 URL 发送数据的变通方法。

您也可以使用 chrome 扩展程序

https://chrome.google.com/webstore/detail/moesif-origin-cors-change/digfbfaphojjndkpccljibejjbppifbc

设置header类型application/x-www-form-urlencoded

let headers = new HttpHeaders();
headers = headers.set('Content-Type', 'application/x-www-form-urlencoded');
headers.append('Access-Control-Allow-Origin','*');
headers.append('Access-Control-Allow-Methods','GET,PUT,POST,DELETE');
headers.append('Access-Control-Allow-Headers','Content-Type');

我迟到了,但仍想 post 回答,以便对其他人有所帮助。 下面的代码对我很有用!

这里是问题的详细答案:

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

我们可以通过多种方式将数据传递到 header 中。 语法不同,但意思相同。

// 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)

在调用中,您可以找到作为 header 传递的字段,如下图所示:

  1. Make changes at the backEnd/Web API side

添加新的 WebApiConfig 文件并添加以下内容。

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 }
            );
        }
    }

在 Global.asax.cs 文件中添加以下事件

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();
            }
        }

并且在 Web API 端,您可以使用以下语句获取该代码:

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

对于以下错误,您可以按照以下步骤操作:

  • 对预检请求的响应未通过访问控制检查:否 ''Access-Control-Allow-Origin'' header 出现在请求的 资源。因此不允许来源 ''http://localhost:4200'' 访问

  • 预检响应没有 HTTP 正常状态。

这段代码对我有用,我可以在 HTTP header 中传递 ID,同样我可以在 Web API 端检索。

谢谢,编码愉快!