Ajax json message for controller by domain, "forbidden" by Access-Control-Allow-Headers headers

I create a simple MVC Controller action that takes some json data and then returns true or false.

[AllowCrossSiteJson] public JsonResult AddPerson(Person person) { //do stuff with person object return Json(true); } 

I call it from javascript:

  function saveData(person) { var json = $.toJSON(person); //converts person object to json $.ajax({ url: "http://somedomain.com/Ajax/AddPerson", type: 'POST', dataType: 'json', data: json, contentType: 'application/json; charset=utf-8', success: function (data) { alert("ok"); } }); } 

Everything works as long as I am in one domain, but as soon as I call it from another domain, I have problems.

There is an “AllowCrossSiteJson” action filter on the controller, which sets the “Access-Control-Allow-Origin” header to “*”, allowing any source to access the controller action.

 public class AllowCrossSiteJsonAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*"); base.OnActionExecuting(filterContext); } } 

However - I get this error in firebug when calling through domains:

OPTIONS http://somedomain.com/Ajax/AddPerson?packageId=3 500 (Internal server error) XMLHttpRequest cannot load http://somedomain.com/Ajax/AddPerson . The Content-Type request header field is not allowed in the Access-Control-Allow-Headers headers.

What is wrong here?

I have been looking through possible solutions for several hours, and this is similar to jquery using OPTIONS (not POST, as I would expect).

If this is really a problem, how can I fix it?

+6
source share
2 answers

I would recommend you JSONP , it is the only truly cross-browser and reliable AJAX cross-domain solution. So you can start by creating a custom action result that will include a JSON response with a callback:

 public class JsonpResult : ActionResult { private readonly object _obj; public JsonpResult(object obj) { _obj = obj; } public override void ExecuteResult(ControllerContext context) { var serializer = new JavaScriptSerializer(); var callbackname = context.HttpContext.Request["callback"]; var jsonp = string.Format("{0}({1})", callbackname, serializer.Serialize(_obj)); var response = context.HttpContext.Response; response.ContentType = "application/json"; response.Write(jsonp); } } 

and then:

 public ActionResult AddPerson(Person person) { return new JsonpResult(true); } 

and finally make an AJAX cross-domain call:

 $.ajax({ url: 'http://somedomain.com/Ajax/AddPerson', jsonp: 'callback', dataType: 'jsonp', data: { firstName: 'john', lastName: 'smith' }, success: function (result) { alert(result); } }); 
+7
source

To fix the Access-Control-Allow-Origin error, you need to include the following header in your answer:

Access-Control-Allow-Headers: Content-Type

Basically, any “tricky” header should be included as a comma-separated list in the header above. Check out the CORS specification for more details:

http://www.w3.org/TR/cors/

"Content-Type" must be enabled because "application / json" does not match the values ​​specified here:

http://www.w3.org/TR/cors/#terminology

+21
source

Source: https://habr.com/ru/post/898018/


All Articles