将响应标头添加到flask web app

Wil*_*voy 7 python header flask web

我有一个使用render_template的烧瓶web应用程序,如下所示.我需要在响应中添加Content-Security-Policy作为附加的http响应头.我尝试了下面的方法,但都失败了,给了我500.

1.

from flask import \
Flask, \
render_template
app = Flask(__name__,template_folder='tmpl')
@app.route('/')
def index():
    resp =make_response(render_template('index.html'))
    resp.headers['Content-Security-Policy']='default-src \'self\'' 
    return resp

if __name__ == '__main__':
app.run(host='0.0.0.0', port=3001)
Run Code Online (Sandbox Code Playgroud)

2.

@app.route('/')
def index():
    resp =render_template('index.html')
    resp.headers.add('Content-Security-Policy','default-src \'self\'') 
    return resp

if __name__ == '__main__':
app.run(host='0.0.0.0', port=3001)   
Run Code Online (Sandbox Code Playgroud)

这可能有什么不对?

在终端上,当我以webhost:3001访问Web应用程序时,我会看到以下内容

127.0.0.1 - - [06/Apr/2015 01:45:01]"GET/HTTP/1.1"500 -

dav*_*ism 23

render_template返回一个字符串,而不是一个响应.从视图返回的字符串会自动包含在Flask的响应中,这就是您可能会感到困惑的原因.使用呈现的模板构造响应.

from flask import make_response
r = make_response(render_template('index.html'))
r.headers.set('Content-Security-Policy', "default-src 'self'")
return r
Run Code Online (Sandbox Code Playgroud)


Sam*_*way 7

处理这个问题的最漂亮的方法是,假设您希望将相同的标题附加到所有响应中,那就是使用 Flask 内置装饰器:

@app.after_request
Run Code Online (Sandbox Code Playgroud)

所以在这种情况下,只需将此功能添加到您的路由模块:

@app.after_request
def add_security_headers(resp):
    resp.headers['Content-Security-Policy']='default-src \'self\''
    return resp
Run Code Online (Sandbox Code Playgroud)

有了这个,您的函数只需像以前一样返回 render_template(...) 值,flask 会自动将其包装在响应中,该响应在返回给客户端之前传递给 after_request 函数。