小编典典

跨域将Ajax json发布到Controller,“不允许” Access-Control-Allow-Headers

ajax

我创建了一个简单的MVC Controller操作,该操作需要一些json数据-然后返回true或false。

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

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

只要我在同一个域中,一切都可以正常工作,但是一旦从另一个域中调用它,我就会遇到问题。

在控制器上是一个动作过滤器“ AllowCrossSiteJson”,它将标题“ Access-Control-Allow-Origin”设置为“
*”,从而允许任何来源访问控制器动作。

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

但是-当跨域调用时,我在Firebug中收到此错误:

选项http://somedomain.com/Ajax/AddPerson?packageId=3500(内部服务器错误)XMLHttpRequest无法加载http://somedomain.com/Ajax/AddPerson。Access-
Control-Allow-Headers不允许请求标头字段Content-Type。

怎么了

我一直在寻找可能的解决方案达数小时之久,这似乎与使用OPTIONS的jquery有关(而不是我期望的POST)。

如果确实存在问题,我该如何解决?


阅读 225

收藏
2020-07-26

共1个答案

小编典典

我建议您JSONP,它是唯一真正的跨浏览器和跨域AJAX的可靠解决方案。因此,您可以从编写自定义操作结果开始,该结果将用回调包装JSON响应:

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

然后:

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

最后执行跨域AJAX调用:

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