上小节我们搭建Flask环境并且写了一个Flask最小应用。接下来讲讲Flask中的URL,在讲解之前,需要了解web的URL后面加’/’和不加’/’有什么区别。请小伙伴思考下面两个链接有什么区别?

https://waliblog.com/python/2019/07/04/python-20.html

https://waliblog.com/python/2019/07/04/python-20.html/

对于用户来说,带’/’和不带’/’是没有区别的,但是对web浏览器来说是不一样的。

为什么url要唯一

对于SEO ,确保页面url的唯一性非常重要。在搜索引擎来眼里,一个 url 就代表一个页面,如果你有多个 url 指向同一个页面,搜索引擎也会把他它们当做不同的页面进行抓取,这不仅浪费的搜索引擎的爬虫资源,而且由于页面内容相同,搜索引擎会当做重复页面,在你的内部页面之间会产生竞争,即使搜索引擎把这几个 url 全部收录了,这个页面的排名也不会理想。

现在来解释上面两个链接在web浏览器中是如果工作的。

当在浏览器中输入第一个链接,会在https://waliblog.com/python/2019/07/04/路径下寻找python-20.html文件。找到就会返回,找不到就会返回404。

在浏览器中输入第二个链接,会在https://waliblog.com/python/2019/07/04/python-20.html/路径下找寻index.html或默认文件(默认文件是可以设置的,根据web服务配置的), 当找到默认文件时,就会返回默认文件否则就返回404

尝试完上面两个链接就会发现,第一个链接可以找到对应的文章,第二个链接找不到

1.Flask中URL

因为url唯一,所以后缀带/和不带/URL在web中是不一样的,但是对于用户来说又是一样的,看下面代码Flask是如何做到

from flask import Flask

app = Flask(__name__)

@app.route('/hello')
def hello_world():
    return 'hello world!'

@app.route('/about/')
def about():
  return 'about'

app.run()

修改完成后重启服务(需要在虚拟环境下重启)

python fisher.py

重启完成后,在浏览器中输入,对比下hello视图 和 about视图有什么区别

http://127.0.0.1:5000/hello

http://127.0.0.1:5000/hello/

http://127.0.0.1:5000/about

http://127.0.0.1:5000/about/

hello视图

在浏览器中输入http://127.0.0.1:5000/hello 发现成功访问到hello页面。

ssl

当在浏览器中输入http://127.0.0.1:5000/hello/ 发现报了一个404 not found错误,改错误是未找到页面,原因在上面已经说明过了,这里过多解释。

ssl

about视图

在浏览器中输入http://127.0.0.1:5000/about/ 成功访问about页面

ssl

在浏览器中输入http://127.0.0.1:5000/about 没有报404错误,也成功访问about页面,在上面代码中,在定义路由时没有定义/about路由,那么Flask是如何找到的,在浏览器中按F12,可以发现浏览器向服务中请求了两次,查看第一次请求,在请求头信息中发现308状态码,该状态码是一个重定向,会让浏览器重新定向到/about/

ssl

上面的解释是小菜个人理解的,下面的解释比较官方:

about 的 URL 是中规中矩的,尾部有一个斜杠,看起来就如同一个文件夹。 访问一个没有斜杠结尾的 URL 时 Flask 会自动进行重定向,帮你在尾部加上一个斜杠。

hello 的 URL 没有尾部斜杠,因此其行为表现与一个文件类似。如果访问这个 URL 时添加了尾部斜杠就会得到一个 404 错误。这样可以保持 URL 唯一,并帮助 搜索引擎避免重复索引同一页面。

兼容带/和不带/URL

上面讲解Flask URL那么多就是想告诉大家如果想要同时兼容带/和不带/ 的URL,那么在定义路由时应该这么写

# 带/和不带/都能访问
@app.route('/about/')

# 只有不带/能够访问
@app.route('/about')

2.url构建

url_for() 函数用于构建指定函数的 URL。它把函数名称作为第一个 参数。它可以接受任意个关键字参数,每个关键字参数对应 URL 中的变量。未知变量 将添加到 URL 中作为查询参数。

为什么不在把 URL 写死在模板中,而要使用反转函数 url_for() 动态构建?

例如,这里我们使用 test_request_context() 方法来尝试使用 url_for()test_request_context() 告诉 Flask 正在处理一个请求,而实际上也许我们正处在交互 Python shell 之中, 并没有真正的请求。参见 本地环境 。

from flask import Flask, escape, url_for

app = Flask(__name__)

@app.route('/')
def index():
    return 'index'

@app.route('/login')
def login():
    return 'login'

@app.route('/user/<username>')
def profile(username):
    return '{}\'s profile'.format(escape(username))

with app.test_request_context():
    print(url_for('index'))
    print(url_for('login'))
    print(url_for('login', next='/'))
    print(url_for('profile', username='John Doe'))

输出:

/
/login
/login?next=/
/user/John%20Doe

Flask

Flask 准备工作(1) Flask URL(2) Flask 路由(3) Flask app.run参数(4) Flask 视图函数返回(5)