### 页面跳转和重定向:
不断更新 需要更多资料文章以及视频加python交流群:553868723
重定向分为永久性重定向和暂时性重定向,在页面上体现的操作就是浏览器会从一个页面自动跳转到另外一个页面。比如用户访问了一个需要权限的页面,但是该用户当前并没有登录,因此我们应该给他重定向到登录页面。
* 永久性重定向:`http`的状态码是`301`,多用于旧网址被废弃了要转到一个新的网址确保用户的访问,最经典的就是京东网站,你输入`www.jingdong.com`的时候,会被重定向到`www.jd.com`,因为`jingdong.com`这个网址已经被废弃了,被改成`jd.com`,所以这种情况下应该用永久重定向。
* 暂时性重定向:`http`的状态码是`302`,表示页面的暂时性跳转。比如访问一个需要权限的网址,如果当前用户没有登录,应该重定向到登录页面,这种情况下,应该用暂时性重定向。
在`flask`中,重定向是通过`flask.redirect(location,code=302)`这个函数来实现的,`location`表示需要重定向到的`URL`,应该配合之前讲的`url_for()`函数来使用,`code`表示采用哪个重定向,默认是`302`也即`暂时性重定向`,可以修改成`301`来实现永久性重定向。
以下来看一个例子,关于在`flask`中怎么使用重定向:
```python
from flask import Flask,url_for,redirect
app = Flask(__name__)
app.debug = True
@app.route('/login/',methods=['GET','POST'])
def login():
return 'login page'
@app.route('/profile/',methods=['GET','POST'])
def profile():
name = request.args.get('name')
if not name:
# 如果没有name,说明没有登录,重定向到登录页面
return redirect()
else:
return name
```
### URL唯一:
`Flask`的`URL`规则是基于`Werkzeug`的路由模块。这个模块的思想是基于`Apache`以及更早的`HTTP`服务器的主张,希望保证优雅且唯一的`URL`。
举个例子:
```python
@app.route('/projects/')
def projects():
return 'project page'
```
上述例子中,当访问一个结尾不带斜线的`URL`会被重定向到带斜线的`URL`上去。这样有助于避免搜索引擎搜索同一个页面两次。
再看一个例子:
```python
@app.route('/about')
def about():
return 'about page'
```
以上例子中,当访问带斜线的`URL`(/about/)会产生一个404("Not Found")错误。
### 关于响应(Response):
视图函数的返回值会被自动转换为一个响应对象,`Flask`的转换逻辑如下:
* 如果返回的是一个合法的响应对象,则直接返回。
* 如果返回的是一个字符串,那么`Flask`会重新创建一个`werkzeug.wrappers.Response`对象,`Response`将该字符串作为主体,状态码为200,`MIME`类型为`text/html`,然后返回该`Response`对象。
* 如果返回的是一个元组,元祖中的数据类型是(response,status,headers),只能包含一个元素。status值会覆盖默认的200状态码,headers可以是一个列表或者字典,作为额外的消息头。
* 如果以上条件都不满足,`Flask`会假设返回值是一个合法的`WSGI`t应用程序,并通过`Response.force_type(rv,request.environ)`转换为一个请求对象。
以下将用例子来进行说明:
第一个例子:直接使用`Response`创建:
```python
from werkzeug.wrappers import Response
@app.route('/about/')
def about():
resp = Response(response='about page',status=200,content_type='text/html;charset=utf-8')
return resp
```
第二个例子:可以使用`make_response`函数来创建`Response`对象,这个更加的方便,因为他封装了默认的`Content-Type`以及`status`等:
```python
from flask import make_response
@app.route('/about/')
def about():
return make_response('about page')
```
第三个例子:通过返回元组的形式:
```python
@app.errorhandler(404)
def not_found():
return 'not found',404
```
第四个例子:自定义响应。自定义响应必须满足三个条件:
* 必须继承自`Response`类。
* 必须实现类方法`force_type(cls,rv,environ=None)`。
* 必须指定`app.response_class`为你自定义的`Response`
以下将用一个例子来进行讲解,`Restful API`都是通过`JSON`的形式进行传递,如果你的`后台`跟前台进行交互,所有的`URL`都是发送`JSON`数据,那么此时你可以自定义一个叫做`JSONResponse`的类来代替`Flask`自带的`Response`类:
```python
from flask import Flask,jsonify
from werkzeug.wrappers import Response
app = Flask(__name__)
class JSONResponse(Response):
default_mimetype = 'application/json'
@classmethod
def force_type(cls,response,environ=None):
if isinstance(response,dict):
response = jsonify(response)
return super(JSONResponse,cls).force_type(response,environ)
app.response_class = JSONResponse
@app.route('/about/')
def about():
return {"message":"about page"}
if __name__ == '__main__':
app.run(host='0.0.0.0',port=8000)
```
此时如果你访问`/about/`这个`URL`,那么在页面中将会显示:
```
{
"message": "about page"
}
```
注意以上例子,如果不写`app.response_class = JSONResponse`,将不能正确的将字典返回给客户端。因为字典不在`Flask`的响应类型支持范围中,那么将调用`app.response_class`这个属性的`force_type`类方法,而`app.response_class`的默认值为`Response`,因此会调用`Response.force_class()`这个类方法,他有一个默认的算法转换成字符串,但是这个算法不能满足我们的需求。因此,我们要设置`app.response_class=JSONResponse`,然后重写`JSONResponse`中的`force_type`类方法,在这个方法中将字典转换成`JSON`格式的字符串后再返回。
不断更新 需要更多资料文章以及视频加python交流群:553868723