“WARNING:tornado.access:405”错误从“localhost”和“file://”来源停止 POST
Posted
技术标签:
【中文标题】“WARNING:tornado.access:405”错误从“localhost”和“file://”来源停止 POST【英文标题】:"WARNING:tornado.access:405" error stopping POST from both "localhost" and "file://" origins 【发布时间】:2017-12-07 14:10:46 【问题描述】:这是一个与这个问题 (Tornado POST 405: Method Not Allowed) 非常相似的问题,但是该问题的死简单答案仍然不起作用。侧边栏还有很多很多类似的问题----->和Tornado无关,也没有给我提供解决方案。
现在我在 OSX 上使用 Firefox。
我的龙卷风代码如下:
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def post(self):
self.write("Hello, world")
get = post # <--------------
application = tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
如果我运行 GET,它可以正常工作,但如果我使用 POST,我会在客户端出现错误 HTTP/1.1 405 Method Not Allowed
,而在服务器端出现错误 WARNING:tornado.access:405 OPTIONS
。我尝试在 file://index.html
和 localhost:8000/index.html
设置中运行 js
我的测试 js 是这样的:
//this one returns the error
U.Ajax.post("http://localhost:8888/", "text", "data = fez hat")
.then(function(result)
console.log(result);
);
//this one works
U.Ajax.get("http://localhost:8888/", "text", "data = fez hat")
.then(function(result)
console.log(result);
);
如果有帮助的话,我的 ajax 代码如下所示:
//tested and functional ajax code, for ease of testing
U = ;
U.Ajax = ;
U.Ajax.send = function(getOrPost, url, dataType, data)
return new Promise( function(resolve, reject)
var request = new XMLHttpRequest();
if(getOrPost == "GET")
request.responseType = dataType || "text";
request.open("GET", url);
else //getOrPost == "POST"
request.open("POST", url);
request.setRequestHeader('Content-type', dataType)
request.onload = function()
if (request.status >= 200 && request.status < 400)
console.log("ajax", request.status+" "+url, request);
resolve(request);
else
request.onerror();
;
request.onerror = function()
var err = "include src '"+url+"' does not exist";
console.log(err)
reject(err)
;
try
request.send(data);
catch(e)
var err = "NS_ERROR_DOM_BAD_URI: Access to restricted URI '"+url+"' denied";
console.log(err)
reject(err)
);
U.Ajax.get = function(url, responseType)
return U.Ajax.send("GET", url, responseType);
U.Ajax.post = function(url, contentType, data)
return U.Ajax.send("POST", url, contentType, data);
编辑 :: 如果我将龙卷风代码更改为等同于 GET POST 和 OPTION,它可以工作,但不正确
class MainHandler(tornado.web.RequestHandler):
def post(self):
print(self.request)
get = options = post # <--------------
我不再收到错误,但是当我打印 self.request
时,我的标题似乎以某种方式设置为“OPTIONS”
HTTPServerRequest(protocol='http', host='localhost:8888', method='OPTIONS', uri='/', version='HTTP/1.1', remote_ip='127.0.0.1', headers= 'Origin': 'null', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Access-Control-Request-Headers': 'content -type', 'Host': 'localhost:8888', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8' , 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:55.0) Gecko/20100101 Firefox/55.0', 'Access-Control-Request-Method': 'POST', 'Connection': '保持活动')
【问题讨论】:
您使用的是什么 javascript 库?U.Ajax
?
不,它几乎是从这个***.com/questions/8567114/…复制而来的
已找到半解,更新问题
“但是当我打印 self.request 时,我的标题似乎以某种方式设置为“OPTIONS”” – ...这可能只是意味着您正在查看 pre - 此类跨域请求所需的飞行请求。
您最好检查一下,是否从浏览器发送了OPTIONS请求(使用crhome的开发者工具或类似工具)。我认为这是javascript问题。
【参考方案1】:
我不再收到错误,但是当我打印 self.request 时,我的标题似乎以某种方式设置为“OPTIONS”
这将是 CORS 飞行前请求。
https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request:
CORS 预检请求是检查 CORS 协议是否被理解的 CORS 请求。
这是一个使用两个 HTTP 请求标头的 OPTIONS 请求:
Access-Control-Request-Method
和Access-Control-Request-Headers
,以及 Origin 标头。浏览器会在需要时自动发出预检请求;在正常情况下,前端开发人员不需要自己制作此类请求。
对于跨域 AJAX 请求,浏览器首先需要与远程服务器核对,是否要使用特定方法和/或特定请求标头接受请求。
这是通过 OPTIONS 请求实现的。当服务器在响应中表示客户端想要发出的实际请求是可接受的时,客户端就会发出该请求。
【讨论】:
【参考方案2】:最近,我遇到了同样的问题。我使用以下代码解决了它:
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def set_default_headers(self):
print('set headers!!')
self.set_header('Access-Control-Allow-Origin', '*')
self.set_header('Access-Control-Allow-Headers', '*')
self.set_header('Access-Control-Max-Age', 1000)
self.set_header('Content-type', 'application/json')
self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
self.set_header('Access-Control-Allow-Headers',
'Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Headers, X-Requested-By, Access-Control-Allow-Methods')
def OPTIONS(self):
pass
application = tornado.web.Application([ (r"/", MainHandler), ])
if name == "main":application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
【讨论】:
这对我有用,但我必须将选项设为小写。 对于其他读者:小心包含Content-type': 'application-json'
:这可能不适合您的应用
@RayB 有哪些选项?我不知道如何听从你的建议。
@javadba def options(self):
以上是关于“WARNING:tornado.access:405”错误从“localhost”和“file://”来源停止 POST的主要内容,如果未能解决你的问题,请参考以下文章