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

XMLHttpRequest изменяет POST на OPTION

У меня есть этот код:

net.requestXHR = function() {
    this.xhr = null;
    if(window.XMLHttpRequest === undefined) {
        window.XMLHttpRequest = function() {
            try {
                // Use the latest version of the activex object if available
                this.xhr = new ActiveXObject("Msxml2.XMLHTTP.6.0");
            }
            catch(e1) {
                try {
                    // Otherwise fall back on an older version
                    this.xhr = new ActiveXObject("Mxsml2.XMLHTTP.3.0");
                }
                catch(e2) {
                    //Otherwise, throw an error
                    this.xhr = new Error("Ajax not supported in your browser");
                }
            }
        };
    }
    else
        this.xhr = new XMLHttpRequest();
}
net.requestXHR.prototype.post = function(url, data) {
    if(this.xhr != null) {
        this.xhr.open("POST", url);
        this.xhr.setRequestHeader("Content-Type", "application/json");
        this.xhr.send(data);
    }
}

    var rs = new net.requestSpeech();
    console.log(JSON.stringify(interaction));
    rs.post("http://localhost:8111", JSON.stringify(interaction));

когда передача выполняется, у меня есть этот журнал:

OPTIONS http://localhost:8111/ [HTTP/1.1 405 Method Not Allowed 74ms]

И в localhost: 8111 У меня есть reslet serverResource, который принимает сообщение, это проблема одной и той же политики происхождения? я модифицировал рестартер, чтобы поместить заголовок allow-origin, и я тестирую его с другим HTTP-запросом GET (в jquery) и работаю нормально. У меня проблема с тем же происхождением, потому что я использую браузер html5, и мой сервер помещает заголовки в ответ, так почему сообщение показывает мне эту ошибку? зачем менять POST для ВАРИАНТА? Спасибо!

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

4b9b3361

Ответ 1

Да, это "проблема с политикой того же происхождения". Вы делаете свой запрос либо на другой сервер, либо на другой порт, а это означает, что это HTTP-запрос межсайтового сайта. Вот что документация должна сказать о таких запросах:

Кроме того, для методов HTTP-запросов, которые могут вызывать побочные эффекты серверных данных (в частности, для HTTP-методов, отличных от GET, или для POST с некоторыми типами MIME), спецификация требует, чтобы браузеры "предваряют" запрос, запрашивая поддерживаемые методы из сервер с методом запроса HTTP OPTIONS, а затем, после "утверждение" с сервера, отправка фактического запроса с фактическим HTTP-запрос.

Более подробное описание в стандарте CORS (раздел "Кросс-ориджин с предполетным периодом" ). Ваш сервер должен разрешить запрос OPTIONS и отправить ответ с заголовками Access-Control-Allow-Origin, Access-Control-Allow-Headers и Access-Control-Allow-Methods, разрешающими запрос. Затем браузер выполнит фактический запрос POST.

Ответ 2

У меня была эта точная проблема с кодом JavaScript, который отправил содержимое ajax.

Чтобы разрешить запрос Cross-Origin с предполетью, я должен был сделать это в .ASPX, который получал петицию:

//Check the petition Method
if (Request.HttpMethod == "OPTIONS")
{
    //In case of an OPTIONS, we allow the access to the origin of the petition
    string vlsOrigin = Request.Headers["ORIGIN"];
    Response.AddHeader("Access-Control-Allow-Origin", vlsOrigin);
    Response.AddHeader("Access-Control-Allow-Methods", "POST");
    Response.AddHeader("Access-Control-Allow-Headers", "accept, content-type");
    Response.AddHeader("Access-Control-Max-Age", "1728000");
}

Вы должны быть осторожны и проверить, какие заголовки задаются вашей петицией. Я проверил тех, кто использовал Fiddler.

Надеюсь, что это послужит кому-то в будущем.

Ответ 3

Как отмечали другие, это дело CORS.

Вот как это делается в NGINX (на основе этот источник):

location / {
    if ($request_method = OPTIONS ) {
        add_header Access-Control-Allow-Origin "http://example.com";
        add_header Access-Control-Allow-Methods "GET, OPTIONS";
        add_header Access-Control-Allow-Headers "Authorization";
        add_header Access-Control-Allow-Credentials "true";
        add_header Content-Length 0;
        add_header Content-Type text/plain;
        return 200;
    }
}

Если вы хотите разрешить запросы CORS из любого источника, замените

add_header Access-Control-Allow-Origin "http://example.com";

с

add_header Access-Control-Allow-Origin "*";

Если вы не используете авторизацию, вам не понадобится этот бит:

add_header Access-Control-Allow-Headers "Authorization";
add_header Access-Control-Allow-Credentials "true";

Для API, который я разрабатываю, мне нужно было ввести в белый список 3 метода запроса: GET, POST и OPTIONS и заголовок X-App-Id, так что это нам, что я закончил:

if ($request_method = OPTIONS ) {
    add_header Access-Control-Allow-Origin "*";
    add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
    add_header Access-Control-Allow-Headers "X-App-Id";
    add_header Content-Length 0;
    add_header Content-Type text/plain;
    return 200;
}