AJAX с jQuery
jQuery — это небольшая библиотека JavaScript, часто используемая для упрощения работы с DOM и JavaScript в целом. Это идеальный инструмент для создания более динамичных веб-приложений путём обмена JSON между сервером и клиентом.
Сам JSON — это очень лёгкий формат передачи данных, очень похожий на то, как выглядят примитивные типы данных Python (числа, строки, словари и списки), который широко поддерживается и очень легко парсится. Он стал популярным несколько лет назад и быстро заменил XML как формат передачи данных в веб-приложениях.
Загрузка jQuery
Для использования jQuery, вам сначала нужно его загрузить, поместить в папку static вашего приложения и убедиться, что оно загружено. В идеале у вас есть шаблон макета, который используется для всех страниц, где вам нужно добавить оператор скрипта в конец вашего <body> для загрузки jQuery:
<script type=text/javascript src="{{
url_for('static', filename='jquery.js') }}"></script>
Другой метод — использование API библиотек AJAX от Google API библиотек AJAX для загрузки jQuery:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="{{
url_for('static', filename='jquery.js') }}">\x3C/script>')</script>
В этом случае вам необходимо поместить jQuery в папку static в качестве резервного варианта, но сначала оно будет пытаться загрузить его напрямую с Google. Это даёт преимущество в том, что ваш веб-сайт, вероятно, будет загружаться быстрее для пользователей, если они посетили по крайней мере один другой веб-сайт перед использованием той же версии jQuery с Google, потому что она уже будет в кэше браузера.
Где находится мой сайт?
Вы знаете, где находится ваше приложение? Если вы разрабатываете, ответ довольно прост: оно находится на локальном сервере по адресу localhost на порту что-то и непосредственно в корневой директории этого сервера. Но что, если вы позже решите переместить своё приложение в другое место? Например, в http://example.com/myapp? На стороне сервера это никогда не было проблемой, потому что мы использовали удобную функцию url_for(), которая могла ответить на этот вопрос за нас, но если мы используем jQuery, мы не должны жёстко кодировать путь к приложению, а сделать его динамичным, так как же это сделать?
Простой метод заключался бы в добавлении тега script на нашу страницу, который устанавливает глобальную переменную для префикса корневого каталога приложения. Что-то вроде этого:
<script type=text/javascript>
$SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
</script>
|safe необходим в Flask до версии 0.10, чтобы Jinja не экранировал закодированную в JSON строку с помощью правил HTML. Обычно это было бы необходимо, но мы находимся внутри блока script , где применяются другие правила.
Информация для специалистов
В HTML тег script объявлен CDATA, что означает, что сущности не будут обработаны. Всё до </script> обрабатывается как скрипт. Это также означает, что между тегами скрипта не должно быть никаких </. |tojson достаточно любезен, чтобы сделать всё правильно и экранировать косые черты для вас ({{ "</script>"|tojson|safe }} отображается как "<\/script>").
В Flask 0.10 это идёт ещё дальше и экранирует все теги HTML с помощью юникод-экранирования. Это позволяет Flask автоматически отмечать результат как безопасный для HTML.
Функции представления JSON
Теперь давайте создадим функцию на стороне сервера, которая принимает два URL-аргумента типа числа, которые должны быть сложены вместе, а затем возвращены приложению в объекте JSON. Это действительно нелепый пример, и обычно вы делаете это только на стороне клиента, но это простой пример, демонстрирующий, как вы можете использовать jQuery и Flask:
from flask import Flask, jsonify, render_template, request
app = Flask(__name__)
@app.route('/_add_numbers')
def add_numbers():
a = request.args.get('a', 0, type=int)
b = request.args.get('b', 0, type=int)
return jsonify(result=a + b)
@app.route('/')
def index():
return render_template('index.html')
Как видите, я также добавил метод index, который рендерит шаблон. Этот шаблон загрузит jQuery, как описано выше, и будет содержать небольшую форму, где мы можем добавить два числа и ссылку для запуска функции на стороне сервера.
Обратите внимание, что мы используем метод get(), который никогда не завершится ошибкой. Если ключ отсутствует, возвращается значение по умолчанию (здесь 0). Кроме того, он может преобразовывать значения в определённый тип (как в нашем случае int). Это особенно полезно для кода, который запускается скриптом (API, JavaScript и т. д.), поскольку в этом случае вам не нужно специальное сообщение об ошибке.
HTML
Ваш шаблон index.html должен либо расширять шаблон layout.html с загруженным jQuery и установленной переменной $SCRIPT_ROOT, либо сделать это вверху. Вот код HTML, необходимый для нашего небольшого приложения (index.html). Обратите внимание, что мы также помещаем скрипт непосредственно в HTML. Обычно лучше иметь его в отдельном файле скрипта:
<script type=text/javascript>
$(function() {
$('a#calculate').bind('click', function() {
$.getJSON($SCRIPT_ROOT + '/_add_numbers', {
a: $('input[name="a"]').val(),
b: $('input[name="b"]').val()
}, function(data) {
$("#result").text(data.result);
});
return false;
});
});
</script>
<h1>jQuery Example</h1>
<p><input type=text size=5 name=a> +
<input type=text size=5 name=b> =
<span id=result>?</span>
<p><a href=# id=calculate>calculate server side</a>
Я не буду подробно рассматривать, как работает jQuery, только очень краткое объяснение небольшого кода выше:
-
$(function() { ... })указывает код, который должен выполняться после того, как браузер закончит загрузку основных частей страницы. -
$('selector')выбирает элемент и позволяет выполнять операции над ним. -
element.bind('event', func)указывает функцию, которая должна выполняться при нажатии пользователем на элемент. Если эта функция возвращаетfalse, стандартное поведение не будет активировано (в данном случае переход на URL#). -
$.getJSON(url, data, func)отправляет запросGETнаurlи отправит содержимое объектаdataв качестве параметров запроса. После получения данных он вызовет указанную функцию со значением возврата в качестве аргумента. Обратите внимание, что мы можем использовать переменную$SCRIPT_ROOT, которую мы установили ранее.
Посмотрите пример исходного кода на GitHub для полного приложения, демонстрирующего код на этой странице, а также то же самое с использованием XMLHttpRequest и fetch.
© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/1.1.x/patterns/jquery/