【问题标题】:Redirecting to URL in Flask重定向到 Flask 中的 URL
【发布时间】:2012-12-29 21:50:49
【问题描述】:

我是 Python 和 Flask 的新手,我正在尝试做与 C# 中的 Response.redirect 等效的操作 - 即:重定向到特定的 URL - 我该怎么做?

这是我的代码:

import os
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello World!'

if __name__ == '__main__':
    # Bind to PORT if defined, otherwise default to 5000.
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)

【问题讨论】:

    标签: python redirect flask


    【解决方案1】:

    有两种方法可以重定向到 Flask 中的 URL。

    1. 例如,您希望在用户登录后将其重定向到另一条路线等。
    2. 您可能还希望将用户重定向到需要一些变量的路由,例如: @app.route('/post/<string:post_id>')

    好吧,为案例 #1 实现烧瓶重定向,很简单,只需这样做:

    from flask import Flask,redirect,render_template,url_for
    app = Flask(__name__)
    
    
    @app.route('/login')
    def login():
        # if user credentials are valid, redirect to user dashboard
        if login == True:
           return redirect(url_for(app.dashboard))
        else:
           print("Login failed !, invalid credentials")
        return render_template('login.html',title="Home Page")
    
    
    @app.route('/dashboard')
    def dashboard():
        return render_template('dashboard.html',title="Dashboard")
    

    要为案例 #2 实现烧瓶重定向,请执行以下操作

    from flask import Flask,redirect,render_template,url_for
    app = Flask(__name__)
    
    
    @app.route('/home')
    def home():
        # do some logic, example get post id
        if my_post_id:
           # **Note:** post_id is the variable name in the open_post route
           # We need to pass it as **post_id=my_post_id**
           return redirect(url_for(app.open_post,post_id=my_post_id))
        else:
           print("Post you are looking for does not exist")
        return render_template('index.html',title="Home Page")
    
    
    @app.route('/post/<string:post_id>')
    def open_post():
        return render_template('readPost.html',title="Read Post")
    

    在视图中可以做同样的事情

    <a href="{{url_for(app.open_post,post_id=my_post_id)}}"></a>
    

    请注意:重定向时始终使用app.homeapp.something..(路由或视图函数名称)而不是使用redirect("/home")。 原因是,如果您出于某种原因将路由示例从 "/home" 修改为 "/index/page",那么您的代码将会中断

    【讨论】:

      【解决方案2】:

      如何在 Flask 中重定向用户/请求

      在您的 API 处理函数中抛出错误会将您的用户重定向到可以处理重定向的错误处理程序。或者,您可以像其他人所说的那样直接致电redirect,但这是重定向未授权用户的另一种方式。为了说明我的意思,我在下面提供了一个示例。

      在用户应该被授权的情况下

      首先让我们假设你有一个受保护的路由,你像这样保护它。

      def handle_api_auth(func):
          """
          **handle_api_auth**
              wrapper to handle public api calls authentications
      
          :param func: a function to be wrapped
          :return: wrapped function
          """
      
          @functools.wraps(func)
          def auth_wrapper(*args, **kwargs):
              api_key: Optional[str] = request.headers.get('x-api-key')
              secret_token: Optional[str] = request.headers.get('x-secret-token')
              domain: Optional[str] = request.base_url
              if is_request_valid(api_key=api_key, secret=secret_token, domain=domain):
                  return func(*args, **kwargs)
              # NOTE: throwing an Error Here will redirect your user to an error handler or alteratively you can just call redirect like everyone else is saying, but this is another way of redirecting unathorized users
              message: str = "request not authorized"
              raise UnAuthenticatedError(status=error_codes.un_auth_error_code, description=message)
      
          return auth_wrapper
      

      is_request_valid的定义如下

      @app_cache.cache.memoize(timeout=15 * 60, cache_none=False)  # timeout equals fifteen minutes // 900 seconds
      def is_request_valid(api_key: str, secret: str, domain: str) -> bool:
          """
          **is_api_key_valid**
              validates api keys on behalf of client api calls
      
          :param api_key: str -> api_key to check
          :param secret: str -> secret token
          :param domain: str -> domain registered for the api_key and secret_token
          :return: bool -> True if api_key is valid
          """
      
          organization_id: str = config_instance.ORGANIZATION_ID
          # NOTE: lets assumy api_keys_view.get_api_key will return the api keys from some database somewhere
          response = api_keys_view.get_api_key(api_key=api_key, organization_id=organization_id)
      
          response_data, status_code = response
          response_dict = response_data.get_json()
      
          if not response_dict.get('status'):
              return False
      
          api_instance: dict = response_dict.get('payload')
          if not isinstance(api_instance, dict):
              return False
      
          domain: str = domain.lower().strip()
          # NOTE accessing the keys this way will throw ValueError if keys are not available which is what we want
          # Any Error which gets thrown Ridirects the Users from the path the user is on to an error handler.
          is_secret_valid: bool = hmac.compare_digest(api_instance['secret_token'], secret)
          is_domain_valid: bool = hmac.compare_digest(api_instance['domain'], domain)
          _request_valid: bool = is_secret_valid and is_domain_valid
      
          return not not api_instance.get('is_active') if _request_valid else False
      
      

      像这样定义你的错误处理程序

      from flask import Blueprint, jsonify, request, redirect
      from werkzeug.exceptions Unauthorized
      
      error_handler = BluePrint('error_handlers', __name__)
      
      @error_handler.app_errorhandler(Unauthorized)
      def handle_error(e : Unauthorized) -> tuple:
          """default unath handler"""
          return jsonify(dict(message=e.description)), e.code if request.headers.get('content-type') == 'application/json' else redirect('/login')
      

      以同样的方式处理其他错误,并注意以防万一请求

      用户被重定向到登录页面的不是 json 如果 json 用户收到未处理的响应,那么它的 直到前端来处理 Unath 错误..

      【讨论】:

        【解决方案3】:

        如果你只是想重定向到一个没有任何状态码或类似的东西的网址,你可以简单地说,这很容易

        from flask import Flask, redirect
        
        app = Flask(__name__)
        
        @app.route('/')
        def redirect_to_link():
            # return redirect method, NOTE: replace google.com with the link u want
            return redirect('https://google.com')
        

        here is the link to the Flask Docs for more explanation

        【讨论】:

          【解决方案4】:

          你必须返回一个重定向:

          import os
          from flask import Flask,redirect
          
          app = Flask(__name__)
          
          @app.route('/')
          def hello():
              return redirect("http://www.example.com", code=302)
          
          if __name__ == '__main__':
              # Bind to PORT if defined, otherwise default to 5000.
              port = int(os.environ.get('PORT', 5000))
              app.run(host='0.0.0.0', port=port)
          

          请参阅the documentation on flask docs. 代码的默认值为 302,因此 code=302 可以省略或替换为其他重定向代码(301、302、303、305 和 307 中的一个)。

          【讨论】:

            【解决方案5】:

            来自Flask API Documentation (v. 2.0.x):

            flask.重定向(location, code=302, Response=None)

            返回一个响应对象(一个 WSGI 应用程序),如果调用该对象,则将客户端重定向到目标位置。支持的代码是 301、302、303、305 和 307。不支持 300 是因为它不是真正的重定向,而 304 是因为它是带有已定义 If-Modified-Since 标头的请求的响应。

            0.6 版中的新功能:位置现在可以是一个 unicode 字符串,即 使用 iri_to_uri() 函数编码。

            参数:

            • location – 响应应该重定向到的位置。
            • code – 重定向状态代码。默认为 302。
            • Response (class) – 实例化响应时使用的响应类。如果未指定,则默认为 werkzeug.wrappers.Response。

            【讨论】:

              【解决方案6】:

              我相信这个问题值得更新。只需与其他方法进行比较即可。

              以下是在 Flask (0.12.2) 中从一个网址重定向 (3xx) 到另一个网址的方法:

              #!/usr/bin/env python
              
              from flask import Flask, redirect
              
              app = Flask(__name__)
              
              @app.route("/")
              def index():
                  return redirect('/you_were_redirected')
              
              @app.route("/you_were_redirected")
              def redirected():
                  return "You were redirected. Congrats :)!"
              
              if __name__ == "__main__":
                  app.run(host="0.0.0.0",port=8000,debug=True)
              

              其他官方参考,here

              【讨论】:

                【解决方案7】:

                为此,您可以简单地使用 flask 中包含的 redirect 函数

                from flask import Flask, redirect
                
                app = Flask(__name__)
                
                @app.route('/')
                def hello():
                    return redirect("https://www.exampleURL.com", code = 302)
                
                if __name__ == "__main__":
                    app.run()
                

                另一个有用的提示(因为您是 flask 的新手),是在初始化 flask 对象后添加 app.debug = True,因为调试器输出有助于找出问题所在。

                【讨论】:

                  【解决方案8】:

                  你可以这样使用:

                  import os
                  from flask import Flask
                  
                  app = Flask(__name__)
                  
                  @app.route('/')
                  def hello():
                       # Redirect from here, replace your custom site url "www.google.com"
                      return redirect("https://www.google.com", code=200)
                  
                  if __name__ == '__main__':
                      # Bind to PORT if defined, otherwise default to 5000.
                      port = int(os.environ.get('PORT', 5000))
                      app.run(host='0.0.0.0', port=port)
                  

                  Here is the referenced link to this code.

                  【讨论】:

                    【解决方案9】:

                    Flask 包含 redirect 函数,用于重定向到任何 url。此外,您可以使用abort 的错误代码提前中止请求:

                    from flask import abort, Flask, redirect, url_for
                    
                    app = Flask(__name__)
                    
                    @app.route('/')
                    def hello():
                        return redirect(url_for('hello'))
                    
                    @app.route('/hello'):
                    def world:
                        abort(401)
                    

                    默认情况下,每个错误代码都会显示一个黑白错误页面。

                    redirect 方法默认采用代码 302。http 状态代码列表here

                    【讨论】:

                      【解决方案10】:
                      flask.redirect(location, code=302)
                      

                      文档可以在here找到。

                      【讨论】:

                        【解决方案11】:
                        #!/usr/bin/env python
                        # -*- coding: utf-8 -*-
                        
                        import os
                        from flask import Flask, redirect, url_for
                        
                        app = Flask(__name__)
                        
                        @app.route('/')
                        def hello():
                            return redirect(url_for('foo'))
                        
                        @app.route('/foo')
                        def foo():
                            return 'Hello Foo!'
                        
                        if __name__ == '__main__':
                            # Bind to PORT if defined, otherwise default to 5000.
                            port = int(os.environ.get('PORT', 5000))
                            app.run(host='0.0.0.0', port=port)
                        

                        看看example in the documentation

                        【讨论】:

                        • 请注意,您将函数名称传递给url_for,然后它会构建一个传递给重定向的 URL,然后您将其返回。
                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2016-06-22
                        • 1970-01-01
                        • 2021-08-27
                        • 2021-07-23
                        • 2011-04-16
                        • 1970-01-01
                        相关资源
                        最近更新 更多