Javascript XMLHttpRequest 将 POST 更改为 OPTION
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8153832/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
XMLHttpRequest changes POST to OPTION
提问by Kalamarico
i have this code:
我有这个代码:
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));
when the send execute, i have this log:
当发送执行时,我有这个日志:
OPTIONS http://localhost:8111/ [HTTP/1.1 405 Method Not Allowed 74ms]
And in localhost:8111 i have a reslet serverResource that accept post, it is problem of same origin policy? i have modify the restlet to put the allow-origin header and i test it with another GET http request (in jquery) and work ok. I have the problem of same origin resolve because i use an html5 browser and my server put the headers in the response, so why the send shows me this error? why change POST for OPTION? Thanks!
在 localhost:8111 我有一个接受 post 的 reslet serverResource,这是同源策略的问题吗?我已经修改了 restlet 以放置 allow-origin 标头,并使用另一个 GET http 请求(在 jquery 中)对其进行测试并且工作正常。我解决了同源问题,因为我使用 html5 浏览器并且我的服务器将标头放在响应中,那么为什么发送会显示这个错误?为什么将 POST 更改为 OPTION?谢谢!
Possible duplicate?: I think no, but it's true, the problem is the same for both questions, but mine are refers since the question that there is an issue with the browser, and the other, first points to jquery. By experience the time does not count for duplicate, the answers are different but it's true that both questions complement each other.
可能重复?:我认为不是,但确实如此,两个问题的问题都相同,但我的问题是指浏览器存在问题,而另一个问题首先指向 jquery。根据经验,时间不算重复,答案是不同的,但这两个问题确实是相辅相成的。
回答by Wladimir Palant
Yes, this is a "problem with same-origin policy". You are making your request either to a different server or to a different port, meaning that it is a cross-site HTTP request. Here is what the documentationhas to say about such requests:
是的,这是一个“同源策略问题”。您正在向不同的服务器或不同的端口发出请求,这意味着它是跨站点 HTTP 请求。以下是文档对此类请求的说明:
Additionally, for HTTP request methods that can cause side-effects on server's data (in particular, for HTTP methods other than
GET
, or forPOST
usage with certain MIME types), the specification mandates that browsers "preflight" the request, soliciting supported methods from the server with an HTTPOPTIONS
request method, and then, upon "approval" from the server, sending the actual request with the actual HTTP request method.
此外,对于可能对服务器数据产生副作用的 HTTP 请求方法(特别是对于除 之外的 HTTP 方法
GET
,或用于POST
某些 MIME 类型的方法),规范要求浏览器“预检”请求,从服务器使用 HTTPOPTIONS
请求方法,然后在服务器“批准”后,使用实际的 HTTP 请求方法发送实际请求。
There is a more detailed description in the CORS standard("Cross-Origin Request with Preflight" section). Your server needs to allow the OPTIONS
request and send a response with Access-Control-Allow-Origin
, Access-Control-Allow-Headers
and Access-Control-Allow-Methods
headers allowing the request. Then the browser will make the actual POST
request.
CORS 标准中有更详细的描述(“Cross-Origin Request with Preflight”部分)。您的服务器需要允许OPTIONS
请求并发送带有Access-Control-Allow-Origin
,Access-Control-Allow-Headers
和Access-Control-Allow-Methods
允许请求的标头的响应。然后浏览器将发出实际POST
请求。
回答by Javier Arteagoitia
I was having this exact problem from a JavaScript code that sent an ajax content.
我从发送 ajax 内容的 JavaScript 代码中遇到了这个确切的问题。
In order to allow the Cross-Origin Request with Preflight I had to do this in the .ASPX that was receiving the petition:
为了允许带有预检的跨源请求,我必须在接收请愿书的 .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");
}
You have to be careful and check what headers are being asked by your petition. I checked those using Fiddler.
您必须小心并检查您的请愿书询问了哪些标题。我使用 Fiddler 检查了那些。
Hope this serves someone in the future.
希望这在未来为某人服务。
回答by Nino ?kopac
As others have pointed out, this is a CORS thing.
正如其他人指出的那样,这是 CORS 的事情。
This is how to handle it in NGINX (based on this source):
这是如何在 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;
}
}
If you want to allow CORS requests from any origin, replace,
如果您想允许来自任何来源的 CORS 请求,请替换,
add_header Access-Control-Allow-Origin "http://example.com";
with
和
add_header Access-Control-Allow-Origin "*";
If you don't use authorization, you won't need this bit:
如果您不使用授权,则不需要此位:
add_header Access-Control-Allow-Headers "Authorization";
add_header Access-Control-Allow-Credentials "true";
For the API I'm developing I needed to whitelist 3 request methods: GET, POST and OPTIONS, and an X-App-Id
header, so this us what I ended up doing:
对于我正在开发的 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;
}
回答by Shailesh Pratapwar
Answer:
回答:
Your browser is initiating a PreFlight OPTIONSrequest.
您的浏览器正在发起PreFlight OPTIONS请求。
Why:Because your request is not a simple request.
为什么:因为您的请求不是简单的请求。
Why it is not a simple request:Because of "Content-Type" = "application/json".
为什么它不是一个简单的请求:因为“Content-Type”=“application/json”。
Solution:Try to use either of below content types :
解决方案:尝试使用以下任一内容类型:
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
- 应用程序/x-www-form-urlencoded
- 多部分/表单数据
- 文本/普通