Ajax json отправляет сообщения в контроллер по доменам, "не разрешено" Access-Control-Allow-Headers - PullRequest
6 голосов
/ 25 сентября 2011

Я создаю простое действие контроллера MVC, которое принимает некоторые данные 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=3 500 (Внутренняя ошибка сервера) XMLHttpRequest не может загрузить http://somedomain.com/Ajax/AddPerson.Поле заголовка запроса Content-Type не разрешено Access-Control-Allow-Headers.

Что здесь не так?

Я просматривал возможныерешения в течение нескольких часов, и, похоже, что-то делать с jquery, используя OPTIONS (не POST, как я ожидал).

Если это действительно проблема, как я могу это исправить?

Ответы [ 2 ]

21 голосов
/ 26 сентября 2011

Чтобы исправить ошибку Access-Control-Allow-Origin, вам нужно включить в ваш ответ следующий заголовок:

Access-Control-Allow-Headers: Content-Type

По сути, любой «непростой» заголовокдолжен быть включен в виде списка через запятую в заголовке выше.Ознакомьтесь со спецификацией CORS для получения более подробной информации:

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

Необходимо включить «Content-Type», поскольку «application / json» не соответствует значениям, определенным здесь:

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

7 голосов
/ 25 сентября 2011

Я бы порекомендовал вам 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);
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...