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

时间:2018-02-09 08:23:31

标签: angular post asp.net-web-api options preflight

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

控制台

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>

Angular Post方法

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

谢谢!

3 个答案:

答案 0 :(得分:2)

我来晚了,但仍想发布答案,因此对其他人可能会有帮助。 下面的代码对我很有吸引力!

这是该问题的详细答案:

  

从Angular端将数据传递到HTTP标头中(请注意,我是   在应用程序中使用Angular4.0 +。

我们可以通过多种方式将数据传递到标头中。 语法不同,但是含义相同。

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

在通话中,您可以找到作为标题传递的字段,如下图所示: enter image description here

  
      
  1. 在后端/ Web API端进行更改
  2.   

添加新的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”标头 资源。因此,不允许来源“ http://localhost:4200” 访问

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

此代码对我有用,我可以在HTTP标头中传递ID,并且可以在Web API端检索相同的代码。

谢谢,祝您编程愉快!

答案 1 :(得分:1)

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

FNR

此内容我已删除

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

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

控制器看起来像这样。

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

Angular POST 方法如下所示

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

这可以解决使用URL发送数据的问题。

答案 2 :(得分:0)

你也可以使用chrome扩展

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

设置标题类型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');