重定向和错误

重定向分为

在页面上体现的操作就是浏览器会从一个页面自动跳转到另外一个页面。比如用户访问了一个需要权限的页面,但是该用户当前并没有登录,因此我们应该给他重定向到登录页面。

分类 http code 作用
永久重定向 301 多用于旧网址被废弃了要转到一个新的网址确保用户的访问,最经典的就是京东网站,你输入www.jingdong.com的时候,会被重定向到www.jd.com,因为jingdong.com这个网址已经被废弃了,被改成jd.com,所以这种情况下应该用永久重定向。
临时重定向 302 表示页面的暂时性跳转。比如访问一个需要权限的网址,如果当前用户没有登录,应该重定向到登录页面,这种情况下,应该用暂时性重定向。

flask中重定向

在flask中,你能够使用

  • redirect()函数重定向用户到其它地方。
  • abort() 函数提前中断一个请求并带有一个错误代码。

重定向是通过 flask.redirect(location, code=302)来实现的。 location表示需要重定向的URL,应该配合url_for()函数来使用,code表示采用哪类重定向,默认为302临时重定向

  1. from flask import Flask,request,redirect,url_for, abort
  2. app = Flask(__name__)
  3. @app.route('/login/')
  4. def login():
  5. abort(401)
  6. return '这是登录页面'
  7. @app.route('/profile/')
  8. def profile():
  9. if request.args.get('name'):
  10. return '个人中心页面'
  11. else:
  12. return redirect(url_for('login')) # 重定向

默认情况下,每个错误代码会显示一个黑白错误页面。如果你想定制错误页面,可以使用 errorhandler()装饰器:

  1. from flask import render_template
  2. @app.errorhandler(404)
  3. def page_not_found(error):
  4. return render_template('page_not_found.html'), 404

响应 response

视图函数的返回值会被自动转换为一个响应对象,flask的转换逻辑如下:

  • 如果返回的是一个合法的响应对象,则直接返回
  • 如果返回的是一个字符串,那么flask会重新创建一个 werkzeug.wrappers.Response对象,Response将该字符串作为主体,状态码为200,MIME类型为text/html,然后热处理该Response对象。
  • 如果返回的是一个元组,元组中的数据类型是(response, status, headers)形式且至少含有一个元素。status值会覆盖默认的200 code,headers可以是一个列表/字典,作为额外的消息头。
  • 如果以上条件都不满足,flask会假设返回值是一个合法的WSGI应用程序,并通过 Response.force_type(rv, request.environ) 转换为一个请求对象

如果你想要获取在视图中得到的响应对象,你可以用函数make_response()
例如404的处理页面

  1. @app.errorhandler(404)
  2. def page_not_found(error):
  3. return render_template('error.html'), 404

你只需要使用make_response()封装返回表达式,获取结果对象并修改,然后返回它:

  1. @app.errorhandler(404)
  2. def page_not_found(error):
  3. resp = make_response(render_template('error.html'), 404)
  4. resp.headers['X-Something'] = 'A value'
  5. return resp

视图函数可以返回哪些值

  1. 可以返回字符串:返回的字符串其实底层将这个字符串包装成了一个Response对象。
  2. 可以返回元组:元组的形式是(响应体,状态码,headers),也不一定三个全部要写,写二个也可以;返回的元组其实在底层也是包装成了一个Response对象
  3. 可以返回Response及其子类

自定义 Response 对象

  1. 继承自Response 类。
  2. 实现方法force_type(cls, rv, environ=None)
  3. 指定app.response_class 为你自定义的Response 对象。
  4. 如果视图函数返回的数据,不是字符串,也不是元组,也不是Response 对象,那么就会将返回值传给force_type,然后再将force_type 的返回值返回给前端
  1. from flask import Flask, jsonify
  2. from werkzeug.wrappers import Resonse
  3. app = Flask(__name__)
  4. class JSONRseponse(Response):
  5. default_mimetype = 'application/json'
  6. @classmethod
  7. def force_type(cls, response, environ=None):
  8. if isinstance(response, dict):
  9. response = jsonify(response)
  10. return super(JSONResponse, cls).force_type(response, enviorn)
  11. app.response_class = JSONResponse
  12. @approute('/about/')
  13. def about():
  14. return {'name': zhansan, 'age': 18}