Reputation: 531
I am trying to send a POST request from my Angular 6 App to an API that sends Emails.
I tested the request with postman and it worked, however when I'm doing the POST request in my Angular app I get errors in my console.
My function in the Angular app:
sendMail(formBody: string): any {
//let url = this.config.origin + "/api/SendEmail";
let url = "http://localhost:49561/api/SendEmail";
let headers = new HttpHeaders();
headers = headers.append('Content-Type', 'application/json');
return this.httpClient.post(url, formBody, { headers })
.pipe(map(res => {
return res;
})).toPromise();
}
I have added the following to my API:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Enable Cors
config.EnableCors();
...
[EnableCors(origins: "http://localhost:4200/contact", headers: "*", methods: "*")]
public class ContactFormsController : ApiController
{
...
These are the warnings and errors I'm getting in the Console:
"Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:49561/api/SendEmail. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)."
"Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:49561/api/SendEmail. (Reason: CORS request did not succeed)."
"ERROR Error: "Uncaught (in promise): HttpErrorResponse: {"headers":{"normalizedNames":{},"lazyUpdate":null,"headers":{}},"status":0,"statusText":"Unknown Error","url":null,"ok":false,"name":"HttpErrorResponse","message":"Http failure response for (unknown url): 0 Unknown Error","error":{"isTrusted":true}}""
EDIT: I have added the following in Web.config:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
and now I'm getting this Error instead of "‘Access-Control-Allow-Origin’ missing":
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:49561/api/SendEmail. (Reason: CORS preflight channel did not succeed)
EDIT:
After removing "content-type : application/json". I got this Error in the console:
ERROR Error: "Uncaught (in promise): HttpErrorResponse: {"headers":{"normalizedNames":{},"lazyUpdate":null},"status":500,"statusText":"Internal Server Error","url":"http://localhost:49561/api/SendEmail","ok":false,"name":"HttpErrorResponse","message":"Http failure response for http://localhost:49561/api/SendEmail: 500 Internal Server Error","error":{"Message":"An error has occurred.","ExceptionMessage":"The specified policy origin 'http://localhost:4200/contact' is invalid. It must not contain a path, query, or fragment.","ExceptionType":"System.InvalidOperationException","StackTrace":" at System.Web.Http.Cors.EnableCorsAttribute.ValidateOrigins(IList`1 origins)\r\n at System.Web.Http.Cors.EnableCorsAttribute.GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Web.Http.Cors.CorsMessageHandler.d__8.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Cors.CorsMessageHandler.d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Cors.CorsMessageHandler.d__4.MoveNext()"}}"
Upvotes: 2
Views: 4199
Reputation: 458
Use attribute ( dont use wildcard for Access-Control-Allow-Methods is not yet supported by all browsers.)
[EnablCors(origins: "*", headers: "*", methods: "GET, POST, PUT, DELETE, OPTIONS")]
In Global
And you have to handle "OPTIONS" method separately in global.asax, as the browser will send a pre-flight request to the server
protected void Application_BeginRequest()
{
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}
Upvotes: 1
Reputation: 3717
Go to your App_start folder and open WebApiConfig.cs
Add following line:
EnableCorsAttribute cors = new EnableCorsAttribute("*", "*", "GET, POST, PUT, DELETE, OPTIONS");
config.EnableCors(cors);
final code:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
EnableCorsAttribute cors = new EnableCorsAttribute("*", "*", "GET, POST, PUT, DELETE, OPTIONS");
config.EnableCors(cors);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
}
You can replace * from localhost:4200 in Origins
Upvotes: 1