Сообщить об ошибке.

Функция make_response модуля flask в Python

Установка заголовков HEADER в функции-представления Flask

Синтаксис:

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