API headers 在前端发出请求时在 Python-Tornado 中不工作

API headers not working in Python-Tornado when front end makes requests

我有一个基本的 CRUD 应用程序,我正在尝试在 localhost:3000 上获取 React-Redux 以向后端发出请求,Python-Tornado(使用 pymongo 作为数据库) 在 127.0.0.1:8888。起初 CORS 是阻止所有请求,但我在网上发现您可以添加 headers 以允许访问 API,所以我这样做了:

class UserHandler(tornado.web.RequestHandler):

    def set_default_headers(self):
        self.set_header("Access-Control-Allow-Origin", "*")
        self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, 
        Content-Type, Accept, Authorization")
        self.set_header('Access-Control-Allow-Methods', 
        'GET,HEAD,OPTIONS,POST,PUT,DELETE')
        self.set_status(204)

    def get(self, id=None):
        {...}

    def post(self):
        {...}

    def delete(self, id):
        {...}

    def put(self, id):
        {...}

def make_app():
    return tornado.web.Application([
        (r"/users/(?P<id>\w+)", UserHandler),
        (r"/user/(?P<id>\w+)", UserHandler),
        (r"/users", UserHandler)
    ],
    debug = True,
    autoreload = True)

if __name__ == "__main__":
    app = make_app()
    port = 8888
    app.listen(port)
    print(f" Server is listening on port {8888}")
    #start server on current thread
    tornado.ioloop.IOLoop.current().start()

现在我的前端允许 GET 请求,但是 POST、PUT 和 DELETE 仍然被阻止并出现以下错误:

Access to XMLHttpRequest at 'http://127.0.0.1:8888/users/625f7194a10940f94e0b8f13' 
from origin 'http://localhost:3000' has been blocked by CORS policy: Response to 
preflight request doesn't pass access control check: The 'Access-Control-Allow- 
Origin' header has a value 'https://localhost:3000' that is not equal to the supplied 
origin.

我查看了多个资源,他们都说只需添加那些 headers,所以我不确定从这里去哪里。

感谢任何帮助,谢谢!

您的反应代码似乎向 http://127.0.0.1:3000 发出请求,但您的 Access-Control-Allow-Origin 只允许 https://localhost:3000。就 headers 而言,这是两个不同的主机。只是让他们都一样。

The answer by Code-Apprentice 正确:请求来源与 Access-Control-Allow-Origin header.

中的值不匹配

但是,为了在开发过程中(在调试模式下)使事情变得更容易,您始终可以允许当前请求来源或只设置通配符值。如果您想从多个设备进行测试,这也很有用(因为您不需要重新配置源 header)。

这是我在项目中所做的:

class MyHandler(web.RequestHandler):
    def set_default_headers(self):
        if self.application.settings.get('debug'): # debug mode is True
            self.set_dev_cors_headers()

    def set_dev_cors_headers(self):
        # For development only
        # Not safe for production
        origin = self.request.headers.get('Origin', '*') # use current requesting origin
        self.set_header("Access-Control-Allow-Origin", origin)
        self.set_header("Access-Control-Allow-Headers", "*, content-type, authorization, x-requested-with, x-xsrftoken, x-csrftoken")
        self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, DELETE, PUT, PATCH')
        self.set_header('Access-Control-Expose-Headers', 'content-type, location, *, set-cookie')
        self.set_header('Access-Control-Request-Headers', '*')
        self.set_header('Access-Control-Allow-Credentials', 'true')

    def options(self, *args, **kwargs):
        # also set a 204 status code for OPTIONS request
        if self.application.settings.get('debug'):
            self.set_status(204)
        else:
            # perhaps do some checks in production mode
            # before setting the status code
            # ...
            self.set_status(204)
        self.finish()