Следующим важным
моментом при разработке сайта является отлавливание некоторых ошибок ответа
сервера. Например, при отсутствии какой-либо страницы пользователь в браузере
увидит следующее:
Это есть
стандартный ответ сервера с кодом 404 – страница не найдена. В таких ситуациях
лучше иметь обработчик для кода 404, который бы возвращал пользователю более
дружественную информацию.
Чтобы создать такой
обработчик, следует использовать специальный декоратор errorhandler с указанием в
нем кода ответа, с которым будет ассоциирована функция представления:
@app.errorhandler(404)
def pageNotFount(error):
return render_template('page404.html', title="Страница не найдена", menu=menu)
Затем, добавим
шаблон page404.html, например,
такой:
{% extends 'base.html' %}
{% block content %}
{{ super() }}
Страница не найдена, вернуться на <a href="/">главную</a> страницу.
{% endblock %}
И при обновлении
страницы, увидим более дружественное сообщение. Причем, код, который возвратит сервер,
будет равен 200 – все хорошо.
Если все же,
требуется при отображении своей собственной страницы возвращать прежний код
404, то это можно реализовать так:
return render_template('page404.html', title="Страница не найдена", menu=menu), 404
Обновляем
страницу и видим в консоли, что сервер возвратил код 404. Однако, при
разработке реальных сайтов, лучше в таких случаях возвращать код 200, т.е. то,
что идет по умолчанию, т.к. поисковым системам «нравится», когда на сайте
страницы отвечают с этим кодом и считается, что это положительно сказывается на
ранжировании их в поисковой выдаче.
Перенаправление запроса
Часто при
создании сайта требуется делать перенаправление пользователя на другую
страницу. Например, пользователь в браузере вводит адрес страницы с формой
авторизации:
http://127.0.0.1:5000/login
И, если он еще
не авторизован, то отображается вот такая страница, а иначе – осуществляется
переадресация на страницу профайла. Давайте для примера реализуем такой простой
функционал. Обработчик представим в следующем виде:
@app.route("/login", methods=["POST", "GET"])
def login():
if 'userLogged' in session:
return redirect(url_for('profile', username=session['userLogged']))
elif request.form['username'] == "selfedu" and request.form['psw'] == "123":
session['userLogged'] = request.form['username']
return redirect(url_for('profile', username=session['userLogged']))
return render_template('login.html', title="Авторизация", menu=menu)
Мы здесь вначале
с помощью сессии проверяем: авторизован ли пользователь, то есть, присутствует
ли ключ 'userLogged' в сессии. И
если это так, то сразу осуществляется переход на страницу профайла. Иначе идет
проверка на тот случай, если пользователь уже передал данные для входа. И для username равным selfedu и пароля 123
осуществляется переход на страницу профайла. Если же обе эти проверки оказались
ложными, то отображается страница с формой авторизации.
Шаблон формы
авторизации можно описать так (файл login.html):
{% extends 'base.html' %}
{% block content %}
{{ super() }}
<form action="/login" method="post" class="form-contact">
<p><label>Имя: </label> <input type="text" name="username" value="" requied />
<p><label>Пароль: </label> <input type="password" name="psw" value="" requied />
<p><input type="submit" value="Войти" />
</form>
{% endblock %}
Прерывание запроса
Чтобы функционал
нашего сайта довести до логического конца, на странице профайла (в обработчике profile) сделаем
проверку: если пользователь самостоятельно в браузере набирает путь, например:
http://127.0.0.1:5000/profile/selfedu
то страница
должна отображаться только в том случае, если пользователь авторизован. Иначе,
завершить вызов ошибкой 401 – доступ запрещен. Это можно сделать так:
@app.route("/profile/<username>")
def profile(username):
if 'userLogged' not in session or session['userLogged'] != username:
abort(401)
return f"Пользователь: {username}"
Смотрите, если в
сессии нет ключа 'userLogged', то вызывается функция abort, которая
указывает серверу вернуть код ошибки 401. Иначе, отображается профайл
пользователя.
Таким образом,
пользователь может смотреть только свой профайл и даже если попытается в
запросе браузера указать логин другого человека, то получит ошибку доступа.