import flask flask.make_response(*args)
*args
- аргументы, которые возможно вернуть из функции-представления.Иногда необходимо установить дополнительные заголовки или изменить существующие в ответе сервера, который генерирует Flask из возвращаемого значения функции-представление. Такими заголовками может быть как дополнительная служебная информация, так и заголовки, содержащие cookie
- ``, тип контента 'Content-Type'
и т. д.
Так как представления не умеют возвращать объекты ответа, но могут возвращать значение, которое Flask автоматически преобразовывает в объект ответа, становится сложно "на лету" как то изменить ответ.
Функция make_response()
модуля flask
используется вместо return
в функции-представлении, для преобразования возвращаемого значения в объекта ответа Response
. После такого преобразования, уже можно спокойно изменять полученный ответ, например, прикрепив/изменив необходимые заголовки и далее вернуть его из функции-представления как обычный ответ. Звучит запутанно, но на примере все становиться понятно.
Например, если функция-представление выглядит следующим образом:
import app from flask import Flask, render_template app = Flask(__name__) @app.route(/index/) # функция-представление def index(): return render_template('index.html', foo=42)
И в ответ необходимо добавить новый заголовок или изменить существующий, то можно сделать что-то вроде этого:
from flask import Flask, render_template, make_response app = Flask(__name__) @app.route(/index/) def index(): # получаем ответ функции-представления response = make_response(render_template('index.html', foo=42)) # дополняем ответ, новым служебным заголовком 'X-NEW-HEADER' response.headers['X-NEW-HEADER'] = 'new header' # можно изменить существующий заголовок response.headers['Content-Type'] = 'text/plain' # возвращаем ответ return response
Функцию make_response()
принимает те же аргументы, которые можно вернуть из функции-представления. Код ниже, например, создает ответ с кодом ошибки 404:
@app.route(/error/) def error_404(): return make_response(render_template('not_found.html'), 404)
Так же, во Flask есть декоратор @after_this_request()
, который больше подходит, если какая то функция, отличная от функции-представления, изменяет ответ Response
. Описание декоратора @after_this_request()
и пример смотрите ниже.
Другой вариант использования этой функции состоит в том, чтобы принудительно ввести возвращаемое значение функции-представления в ответ приложения, что полезно для создания декораторов-представлений:
resp_view_function = make_response(view_function()) resp_view_function.headers['X-NEW-HEADER'] = 'new header' app.add_url_rule('/users/', view_func=resp_view_function)
Дополнительно смотрите список заголовков, которые поддерживает браузер и на что они влияют: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers.
Обратите внимание, что заголовки ответа сервера, не имеет ничего общего с заголовками HTML-страницы, то есть, с содержимым тега <head> ... </head>
Внутренне, функция make_response
выполняет следующие действия:
flask.Flask.make_response()
.flask.Flask.make_response()
как кортеж.flask.after_this_request(f)
:Функция-декоратор @after_this_request()
выполняет функцию f
после этого запроса. Такое поведение полезно для изменения объектов ответа Response
.
Функция-декоратор @after_this_request()
вызывается с объектом Response
и должна вернуть тот же или новый объект ответа.
@app.route('/') def index(): @after_this_request def add_header(response): response.headers['X-Foo'] = 'Parachute' return response return 'Hello World!'
Это более подходящий вариант, если какая то функция, отличная от функции-представления, хочет изменить ответ. Подумайте о декораторе, который добавляет несколько заголовков без преобразования возвращаемого значения в объект ответа Response
, вместо использования make_response()
.
make_response()
в веб приложении на Flask.Имитация встроенной во Flask функции редиректа/перенаправления на другой URL-адрес flask.redirect()
.
@app.route('/redirect/') def redirect(): response = make_response('', 301) response.headers['Location'] = 'https://example.com/new_url' return response
Имитация встроенной во Flask функции flask.send_file()
. Загрузим изображение из static/images
и покажем его в браузере. При этом необходимо указать заголовок 'Content-Type'
, чтобы браузер расценивал принятые данные, как изображения PNG
.
@app.route("/show_png/<img>") def show_png(img): load_png = None # читаем изображение with app.open_resource( app.root_path + '/static/images/img', mode='rb') as fp: load_png = fp.read() # если изображение не прочиталось if load_png is None: # прерываем запрос с ошибкой abort(404) # отдаем изображение в ответе response = make_response(load_png) # говорим браузеру, что это изображение response.headers['Content-Type'] = 'image/png' # возвращаем ответ клиенту return response