当前端提出请求时,API标头不在Python-Tornado工作

发布于 2025-01-22 22:04:19 字数 1073 浏览 2 评论 0原文

我有一个基本的CRUD应用程序,并且我正在尝试在Localhost上获得React-Redux:3000,以向后端提出请求,Python-Tornado(使用Pymongo用于数据库),在127.0.0.0.1:8888。起初,CORS阻止了所有请求,但是我在网上发现您可以添加标题以允许访问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"
              

I've got a basic CRUD application, and I'm trying to get React-Redux on localhost:3000 to make requests to the backend, Python-Tornado (using pymongo for the database) at 127.0.0.1:8888. At first CORS was blocking all requests, but I found online that you can add headers to allow access to the API, so I did like this:

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()

Now my Front end is allowing GET requests, but POST, PUT, and DELETE are still getting blocked with the following error:

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.

I've looked around at multiple resources and they all say to simply add those headers, so I'm not sure where to go from here.

Any help is appreciated, thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

回心转意 2025-01-29 22:04:19

code-apprentice by code-apprentice 是正确的:请求原点与access> access-access-control-允许原素标头。

但是,为了在开发过程中(在调试模式下)保持更容易的状态,您可以始终允许当前的请求来源或设置通配符值。如果您想从多个设备进行测试(因为您不需要重新配置原始标头)也将很有用。

这就是我在项目中所做的:

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()
    

The answer by Code-Apprentice is correct: the request origin doesn't match the value in Access-Control-Allow-Origin header.

However, to keep things easier during development (while in debug mode), you can always allow the current request origin or just set wildcard values. This will also be useful if you want to test from multiple devices (as you won't need to reconfigure the origin header).

This is what I do in my projects:

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()
    
逆夏时光 2025-01-29 22:04:19

您的React代码似乎向http://127.0.0.1:3000提出了请求/localhost:3000 。就标题而言,这是两个不同的主机。只要使它们俩都一样。

Your react code appears to make a request to http://127.0.0.1:3000, but your Access-Control-Allow-Origin only allows https://localhost:3000. These are two different hosts as far as the headers are concerned. Just make them both the same.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文