Подтвердить что ты не робот

Кросс-доменный запрос POST с использованием совместного использования ресурсов Cross-Origin без возврата данных

Я отправляю данные через домен через запрос POST, но ответ не работает, в частности, обработчик jQuery никогда не получает вызов.

Используемое свойство: Django, Apache, jQuery.

Итак, я настроил запрос, похожий на этот:

$.ajax({
    url: "http://somesite.com/someplace",
    type: "POST",
    cache: false,
    dataType: "json",
    data: { ... },
    success: function( msg ) {
        alert(msg);
    },
});

Как вы хорошо знаете, CORS позволяет мне ответить на запрос OPTIONS, чтобы сказать "Да, вы можете ПОСТИТЬ мне", Что я делаю. Firebug подтверждает, что я получаю код состояния 200 и что тип возврата фактически application/json. Тем не менее, Firebug также подтверждает, что обработчик успеха в вышеупомянутом случае не вызывается.

Для справки, мой ответ на OPTIONS:

elif request.method == "OPTIONS":
    response = HttpResponse("")
    response['Access-Control-Allow-Origin'] = "*"
    response['Access-Control-Allow-Methods'] = "POST, GET, OPTIONS"
    response['Access-Control-Allow-Headers'] = "X-Requested-With"
    return response

В отличие от этого, если я настроил обработчик complete: function()..., он работает.

Итак, вопрос: что происходит (или нет) и почему? Я получаю данные в порядке, я просто хотел бы вернуть ответ.


Обновить. Это исправляет мою проблему в некоторых браузерах, но поскольку у меня нет полного объяснения этого поведения, я оставляю его открытым.

Хорошо, поэтому я прочитал руководство и что я понимаю, применяемый алгоритм примерно такой:

  • Пользовательские агенты могут выполнять предполетный вызов. Это запрос OPTIONS. Идея состоит в том, что они делают этот запрос, который дает им ответ в отношении запрошенного ресурса, который они затем должны кэшировать. Я не передаю поле max-age, поэтому я подозреваю, что пока успех возвращается и разрешен X-запрос, в кэше пользовательского агента нет ничего, что позволило мне это сделать, поэтому применяются правила по умолчанию (изолировать запрос).
  • Когда вы делаете фактический запрос, я считаю, что пользовательский агент должен проверять кеш-память перед полетом для получения разрешений. Без моего поля максимального возраста я считаю, что он не находит эти разрешения. Однако ответ с теми же заголовками на POST позволяет Firefox и Google Chrome просматривать ответ. Опера не может. На данный момент IE остается непроверенным.

В настоящее время я не понимаю, и из руководства (по крайней мере, мне) неясно, должен ли запрос CORS также отвечать на эти заголовки в запросе, а также на OPTIONS. Я буду экспериментировать с заголовком Max-Age и посмотреть, что это разрешает или не позволяет. Тем не менее, мне все еще не хватает определенного авторитетного понимания по этому вопросу, поэтому, если кто-то здесь знает, я все уши.

4b9b3361

Ответ 1

Хорошо, поэтому я считаю, что правильный способ сделать это:

if request.method == "POST":
    response = HttpResponse(simplejson.dumps(data),mimetype='application/json')
    response['Access-Control-Allow-Origin'] = "*"
    return response
elif request.method == "OPTIONS":
    response = HttpResponse("")
    response['Access-Control-Allow-Origin'] = "*"
    response['Access-Control-Allow-Methods'] = "POST, OPTIONS"
    response['Access-Control-Allow-Headers'] = "X-Requested-With"
    response['Access-Control-Max-Age'] = "1800"
else:
    return HttpResponseBadRequest()

Это основано на документации которую я выкопал из Mozilla по запрограммированным запросам.

Итак, я верю, что это произойдет:

  • Если в кэше preflight нет ничего, OPTIONS отправляется с X-Requested-With, установленным в XMLHttpRequest, я считаю, что это необходимо, чтобы разрешить Javascript доступ к чему-либо вместе с заголовком Origin.
  • Сервер может проверить эту информацию. Это безопасность CORS. В моем случае я отвечаю "любое происхождение будет" и "вам разрешено отправить X-Requested-With вещь". Я говорю, что OPTIONS и POST разрешены и что этот ответ должен быть кэширован в течение 30 минут.
  • Затем клиент переходит вперед и делает POST, который работал до этого.
  • Я первоначально изменил ответ, включив Allow-Methods и Allow-Headers, но в соответствии с обменом в вышеупомянутой связанной документации это не требуется. Это имеет смысл, проверка доступа уже выполнена.
  • Я полагаю, что происходит следующее: проверка доступа к ресурсам, описанная здесь. В принципе, как только указанный запрос был сделан, браузер снова проверяет поле Allow-Origin на достоверность, это по запросу, например POST. Если это пройдет, клиент может получить доступ к данным, если нет, запрос уже завершен, но браузер отказывает в доступе к этим данным фактическому доступу на стороне клиента (Javascript).

Я считаю, что это правильное резюме того, что происходит, и в любом случае оно работает. Если я не прав, пожалуйста, кричите.

Ответ 2

Для любых будущих поисковиков, которые могут столкнуться с этой публикацией, следующим ресурсом является рабочий проект W3C 2008, в котором подробно рассматривается CORS.

http://www.w3.org/TR/2008/WD-access-control-20080912/

По состоянию на момент публикации, следует отметить, что Chromium специально и, вероятно, все WebKit имеет ошибку, которая предотвращает выполнение значения заголовка Access-Control-Max-Age. Подробности об этом можно найти на странице обсуждения Chromium Issue 131368. В итоге - на данный момент браузеры на основе WebKit будут переопределять то, что сервер возвращает как значение здесь, с 600 (10 минут).

Ответ 3

ПРОСЬБА:

 $.ajax({
            url: "http://localhost:8079/students/add/",
            type: "POST",
            crossDomain: true,
            data: JSON.stringify(somejson),
            dataType: "json",
            success: function (response) {
                var resp = JSON.parse(response)
                alert(resp.status);
            },
            error: function (xhr, status) {
                alert("error");
            }
        });

ОТВЕТ:

response = HttpResponse(json.dumps('{"status" : "success"}'))
response.__setitem__("Content-type", "application/json")
response.__setitem__("Access-Control-Allow-Origin", "*")

return response

Ответ 4

Я не думаю, что это возможно по соображениям безопасности. Единственный перекрестный домен ajax, который разрешает браузер, может быть выполнен с использованием JSONP, и это исключительно запросы GET.

Это будет работать:

$.ajax({
    url: "http://somesite.com/someplace",
    type: "GET",
    cache: false,
    dataType: "JSONP",
    data: { ... },
    success: function( msg ) {
        alert(msg);
    },
});

Это не будет:

$.ajax({
    url: "http://somesite.com/someplace",
    type: "POST",
    cache: false,
    dataType: "JSONP",
    data: { ... },
    success: function( msg ) {
        alert(msg);
    },
});