在单元测试Flask应用程序I时,首先意外地省略了follow_redirects=True
参数,这导致以下测试失败:
from unittest import TestCase
class TestFlask(TestCase):
def test_settings(self):
# user not logged in
r = self.app.get("/user/settings", follow_redirects=False)
data = r.data.decode('utf-8')
self.assertIn("Sign In", data)
对于此页面(/ user / settings),用户需要登录,并且通常会被重定向到登录页面,其中包含“登录”字样。当然,使用follow_redirects=False
我得到一个AssertionError
(注意自动生成的HTML):
AssertionError: 'Sign In' not found in '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n<title>Redirecting...</title>\n<h1>Redirecting...</h1>\n<p>You should be redirected automatically to target URL: <a href="/user/login?next=%2Fuser%2Fsettings">/user/login?next=%2Fuser%2Fsettings</a>. If not click the link.'
如何自定义未被遵循的302重定向生成的HTML?
from flask import Flask
app = Flask(__name__)
# ...
@app.errorhandler(404)
def page_not_found(e):
return "page not found, {}".format(e)
@app.errorhandler(302)
def redirect(e):
return "redirecting... {}".format(e)
采用与自定义404页面相同的方法在启动Web服务器时会导致KeyError: 302
。我知道302并不表示错误,因此,尝试使用errorhandler
注定会失败。但是,我没有找到任何替代方案。
对于RFC 7231:
服务器的响应有效负载通常包含一个短超文本注释,其中包含指向不同URI的超链接。
但实际上,大多数用户代理完全忽略了重定向有效负载。当浏览器遇到Location
标头时,它立即开始重定向到新页面,因此从不呈现302响应的有效负载。
如果您关心非浏览器用户代理在取消关注重定向上的行为(为什么?),您可以像平常一样构建响应(例如使用flask.render_template
)并手动设置response.status = 302
和response.headers['Location'] = '/path/to/redirect/to'
,而不是使用flask.redirect
帮助函数。如果您发现自己一直在做这类事情,您可以定义自己的redirect
函数来代替,或者您可以编写一个Werkzeug中间件来为您转换重定向响应。