问题
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!
回答1:
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 :
- 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!!
回答2:
I finally found a work around. what i did is i removed custom headers from web.config file. i.e,
<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>
This content i removed
and in WebApiConfig.cs i did following changes
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);
and Controller Looks like this.
[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");
}
}
and Angular POST Method looks like following
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());
}
This is work around to send data with URL.
回答3:
also u can use chrome extension
https://chrome.google.com/webstore/detail/moesif-origin-cors-change/digfbfaphojjndkpccljibejjbppifbc
set header type 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');
来源:https://stackoverflow.com/questions/48701518/response-for-preflight-has-invalid-http-status-code-404-in-my-angular-project-wh