首页 文章

Tornado服务器:启用CORS请求

提问于
浏览
8

我有一个简单的龙卷风服务器,它有类:

class BaseHandler(tornado.web.RequestHandler):
    def set_default_headers(self):
        print "setting headers!!!"
        self.set_header("Access-Control-Allow-Origin", "*")

当发出常规(无CORS)请求时,服务器按预期应答,包括Access-Control-Allow-Origin标头 . 但是当我发出来自不同域的帖子请求时(使用 jQuery.post ),响应为404并显示错误:“XMLHttpRequest无法加载http://dev-machine:8090/handshake . 请求的资源上没有'Access-Control-Allow-Origin' Headers . 因此不允许原点'http://localhost:8090'访问 . 响应的HTTP状态代码为404.“

你能告诉我是否遗漏了什么吗? (另一个 Headers /其他配置/其他)

3 回答

  • 7

    您的代码缺少预检, OPTIONS 请求 .

    https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

    跨源资源共享标准的工作原理是添加新的HTTP标头,允许服务器描述允许使用Web浏览器读取该信息的起源集 . 此外,对于可能对用户数据造成副作用的HTTP请求方法(特别是对于GET以外的HTTP方法,或对某些MIME类型的POST使用),规范要求浏览器“预检”请求,请求支持的方法从具有HTTP OPTIONS请求方法的服务器,然后,在服务器“批准”时,使用实际的HTTP请求方法发送实际请求 . 服务器还可以通知客户端是否应随请求一起发送“凭据”(包括Cookie和HTTP身份验证数据) .

    要实现预检处理程序,只需添加具有相同 Headers 且没有正文的选项处理程序 .

    class BaseHandler(tornado.web.RequestHandler):
    
        def set_default_headers(self):
            print "setting headers!!!"
            self.set_header("Access-Control-Allow-Origin", "*")
            self.set_header("Access-Control-Allow-Headers", "x-requested-with")
            self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
    
        def post(self):
            self.write('some post')
    
        def get(self):
            self.write('some get')
    
        def options(self):
            # no body
            self.set_status(204)
            self.finish()
    

    edit

    我已将 x-requested-with 标头添加到允许列表中 . 这里是简单的jquery示例:

    $.ajax({
       url: "http://some_tornado/api",
       type: "POST",
       crossDomain: true,
       data: 'some_data',
       success: function (response) {
         alert(response);
       },
       error: function (xhr, status) {
         alert("error");
       }
     });
    

    还有一些关于科尔斯的好文章 - http://dev.housetrip.com/2014/04/17/unleash-your-ajax-requests-with-cors/

  • 1

    kwarunek的答案让我找到了解决PUT和DELETE请求问题的方法 . 唯一的问题是,该解决方案对于使用GET和POST的示例而言过于合适 . 在这种情况下的线

    self.set_header("Access-Control-Allow-Origin", "*")
    

    实际上是足够的(如果浏览器之前没有阻止CORS) . 它与PUT和DELETE请求最相关 . 在网络级别上发生的事情可能比在GET / POST情况下稍微复杂一些 .

    "If the request is a "非简单" request, the browser first sends a data-less "预检" OPTIONS request, to verify that the server will accept the request. A request is non-simple when using an HTTP verb other than GET or POST (e.g. PUT, DELETE)." cf. non-simple requests

    class BaseHandler(tornado.web.RequestHandler):
    
        def set_default_headers(self):
            print("setting headers!!!")
            self.set_header("Access-Control-Allow-Origin", "*")
            self.set_header("Access-Control-Allow-Headers", "x-requested-with")
            self.set_header('Access-Control-Allow-Methods', ' PUT, DELETE, OPTIONS')
    
        def options(self):
            # no body
            self.set_status(204)
            self.finish()
    

    现在,从 BaseHandler 继承的所有处理程序都具有完全CORS功能:

    class MyHandler(BaseHandler):
    
        def put(self):
            self.write('some post')
    
        def delete(self):
            self.write('some get')
    
  • 30

    即使有了以前的答案,我仍然有以下CORS错误:

    跨源请求被阻止:同源策略不允许在http://127.0.0.1:9999/home?message=Input%20to%20API读取远程资源..(原因:缺少令牌'access-control-allow-来自CORS预检 Channels 的CORS Headers “访问控制允许 Headers ”的起源 .

    并且 solution 也允许 Headers :

    class BaseHandler(tornado.web.RequestHandler):
    
        def set_default_headers(self):
            print("setting headers!!!")
            self.set_header("access-control-allow-origin", "*")
            self.set_header("Access-Control-Allow-Headers", "x-requested-with")
            self.set_header('Access-Control-Allow-Methods', 'GET, PUT, DELETE, OPTIONS')
            # HEADERS!
            self.set_header("Access-Control-Allow-Headers", "access-control-allow-origin,authorization,content-type") 
    
        def options(self):
            # no body
            self.set_status(204)
            self.finish()
    

相关问题