上小节我们搭建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()
修改完成后重启服务(需要在虚拟环境下重启)
重启完成后,在浏览器中输入,对比下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页面。
当在浏览器中输入http://127.0.0.1:5000/hello/
发现报了一个404 not found错误,改错误是未找到页面,原因在上面已经说明过了,这里过多解释。
about视图
在浏览器中输入http://127.0.0.1:5000/about/
成功访问about页面
在浏览器中输入http://127.0.0.1:5000/about
没有报404错误,也成功访问about页面,在上面代码中,在定义路由时没有定义/about
路由,那么Flask是如何找到的,在浏览器中按F12,可以发现浏览器向服务中请求了两次,查看第一次请求,在请求头信息中发现308状态码,该状态码是一个重定向,会让浏览器重新定向到/about/
中
上面的解释是小菜个人理解的,下面的解释比较官方:
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() 动态构建?
- 反转通常比硬编码 URL 的描述性更好
- 你可以只在一个地方改变 URL ,而不用到处乱找
- URL 创建会为你处理特殊字符的转义和 Unicode 数据,比较直观
- 生产的路径总是绝对路径,可以避免相对路径产生副作用
- 如果你的应用是放在 URL 根路径之外的地方(如在
/myapplication
中,不在 / 中), 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