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. По опыту время не учитывается для дублирования, ответы разные, но верно, что оба вопроса дополняют друг друга.
Ответы
Ответ 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;
}