Ответ на предпечатную проверку имеет недопустимый код состояния http 404 в моем угловом проекте при использовании веб-API

Я знаю, что это проблема CORS. Я включил Cors на стороне веб-сервера API. Метод Get работает нормально, но при работе с методом post я сталкиваюсь с проблемой. Пожалуйста, кто-нибудь ответит мне очень простым примером как на веб-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>

Угловой пост метод

    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 ответа

Решение

Я наконец нашел работу вокруг. я удалил пользовательские заголовки из файла 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>

Это содержание я удалил

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

и угловой метод 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.

Я опаздываю, но все еще хочу опубликовать ответ, чтобы другим было полезно. Ниже код работает для меня как шарм!

Вот подробный ответ на вопрос:

Передайте данные в заголовок HTTP со стороны Angular (обратите внимание, я использую 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)

В вызове вы можете найти поле, переданное в качестве заголовка, как показано на рисунке ниже:

  1. Вносить изменения на стороне backEnd/Web API

Добавьте новый файл 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 ok.

Этот код работает для меня, я могу передать идентификатор в заголовке HTTP, и то же самое я могу получить на стороне веб-API.

Спасибо и счастливого кодирования!

Также вы можете использовать расширение 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');
Другие вопросы по тегам