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] 

而在本地主机:8111我有一个reslet serverResource接受post,这是同源策略的问题? 我已经修改restlet放置允许来源的头,我用另一个GET请求(在jquery中)testing它,并确定工作。 我有同样的来源解决问题,因为我使用一个HTML5浏览器,我的服务器把头放在响应,所以为什么发送给我这个错误? 为什么要改变POST的OPTION? 谢谢!

可能的重复?:我认为不是,但是这是真的,这两个问题的问题是相同的,但是我的指的是因为浏览器存在问题的问题,另一个首先指向jQuery。 根据经验,时间不重复,答案是不同的,但两个问题是相辅相成的。

是的,这是一个“同源政策的问题”。 您正在向不同的服务器或不同的端口发送请求,这意味着这是一个跨站点的HTTP请求。 以下是关于这些请求的文件说明 :

此外,对于可能对服务器数据造成副作用的HTTP请求方法(特别是对于GET以外的HTTP方法,或对于某些MIMEtypes的POST方法),规范要求浏览器“预检”请求,请求支持的方法从服务器使用HTTP OPTIONS请求方法,然后在从服务器“批准”时,用实际的HTTP请求方法发送实际的请求。

CORS标准有更详细的描述(“预检的跨源请求”部分)。 您的服务器需要允许OPTIONS请求,并发送允许请求的Access-Control-Allow-OriginAccess-Control-Allow-HeadersAccess-Control-Allow-Methods标题的响应。 然后浏览器将发出实际的POST请求。

我从发送ajax内容的JavaScript代码中得到了这个确切的问题。

为了允许使用预检的跨源请求,我必须在接收请求的.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检查了那些。

希望这能为将来的人服务。

正如其他人指出的,这是一个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请求,请replace,

 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,我需要将三个请求方法列入白名单: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; }