Веб-разработка — это огромное дело; плавильный котел различных технологий, библиотек и фреймворков, постоянно развивающийся с течением времени. Как начинающему веб-разработчику, мне было сложно узнать все нюансы работы этих технологий, когда и где их следует применять, а также особенности их интеграции в мои собственные проекты.

К счастью, мы живем в эпоху, когда огромная база знаний и сообщество разработчиков находятся прямо у нас под рукой. Практически для всех проблем веб-разработки есть учебные пособия и темы для обсуждения, которые каждый может увидеть на таких сайтах, как StackOverflow и Medium.

Однако, пытаясь создать свои собственные приложения в последние несколько месяцев, я не мог не заметить недостатки этих ресурсов. Учебники будут сильно различаться по способу решения проблемы, но будет неясно, какое влияние эти различия окажут на приложение. Другие учебники украшали свои примеры посторонними библиотеками, использовали сложные примеры или просто показывали код без адекватного объяснения того, как он работает. Поскольку я люблю понимать каждую написанную строчку, я остался недоволен.

Вдохновленный собственными трудностями, я решил написать статью, в которой попытаюсь ответить на вопрос веб-разработки, используя несколько очень простых примеров, объясняя при этом различия между ними. Это может стать первой записью в серии подобных сообщений.

—

Введение

Абсолютно важной частью многих современных веб-приложений является способность клиента и сервера взаимодействовать друг с другом способами, которые выходят за рамки обслуживания HTML-страниц. Примеры включают в себя отправку клиентами учетных данных на серверы при попытке входа в систему или проверку того, занято ли имя пользователя при попытке зарегистрироваться. Или, возможно, информационная панель веб-сайта извлекает сообщения новостей и объявления при загрузке, но сервер также отправляет уведомления в режиме реального времени при создании нового сообщения.

В таких сценариях сбор и представление данных обычно обрабатывается так называемым «внешним интерфейсом», который является частью приложения, с которой непосредственно взаимодействует пользователь, в то время как обработкой и хранением данных занимается «внутренняя часть», в которую входят серверы и базы данных. Эти части часто разрабатываются независимо и даже могут быть написаны на совершенно разных языках программирования. По этой причине передача информации между ними не так проста, как доступ к переменной.

Поэтому, когда я начал веб-разработку, одним из первых больших вопросов, которые у меня возникли, был:
Как мне заставить мой внешний интерфейс общаться с моим внутренним?

Это руководство призвано дать некоторые ответы на этот вопрос, в частности, для связи между серверной частью Express.js и внешним интерфейсом с поддержкой JavaScript.

Подготовка

Учебник был написан и протестирован на Node.js 10.7.0 / npm 6.3.0. Предполагается, что у вас установлен Node.js + npm и вы имеете базовые знания HTML, JavaScript, Node.js и Express.js.

Создайте новый каталог, затем откройте в нем терминал/командную строку и выполните следующее:

npm init -y
npm install express
npm install body-parser

Затем создайте в этом каталоге два файла: index.js и index.html. Вы можете сделать это в терминале UNIX с помощью touch index.js или в командной строке Windows с помощью type nul >> index.js . Получив файлы, используйте их для создания простого сервера реагирования, который обслуживает index.html:

Убедитесь, что он работает, запустив node index.js и открыв http://localhost:4001:

Итак, вы готовы начать экспериментировать!

HTTP-запросы

Типичный способ взаимодействия клиента и сервера — HTTP-запросы, когда клиент сообщает серверу, что нужно получить или изменить размещенный ресурс. Некоторые примеры методов HTTP-запроса включают GET, POST, UPDATE и DELETE.

Один из способов представить это так: сервер прослушивает клиентские запросы определенных типов, направленные на определенные адреса, и отправляет ответ в зависимости от того, какой из них он получил. Это может быть файл HTML, как в примере «Подготовка», но это также может быть текст, данные JSON или другие типы файлов. Таким образом, способ, которым внешнее приложение может взаимодействовать с внутренним сервером, заключается в том, что клиент отправляет запрос на некоторый адрес сервера и получает что-то в ответ. Интерфейс, через который это происходит, называется «интерфейсом прикладного программирования» сервера или API.

Хотя изначально это использовалось для извлечения статических файлов, по мере роста Интернета были введены серверные языки программирования, такие как PHP, для динамического создания HTML-страниц в ответ на информацию, предоставленную клиентами. Мы можем воссоздать этот сценарий с помощью Express. Для этого мы добавим форму на нашу HTML-страницу, которая предоставляет имя пользователя через POST-запрос к ‘/user’. Когда сервер получит этот запрос, мы скажем ему ответить некоторым HTML:

Вы можете себе представить, что наш сервер прослушивает POST-запросы, направленные на /user, и когда он их слышит, он ищет внутри имя пользователя и отправляет в ответ уникальную страницу. Мы можем проверить это, перейдя по адресу http://localhost:4001, введя имя и нажав Отправить:

Поздравляем, наш интерфейс и сервер поделились информацией! Хотя этот пример работает, при написании всего приложения таким образом возникают серьезные проблемы:

  • Каждый раз, когда мы хотим отправить или получить данные, нам пришлось бы использовать форму и открывать другую веб-страницу или перезагружать текущую страницу.
  • Сервер должен тратить время на создание страницы и отправку ее в полном объеме при каждом запросе. Это потребляет много ресурсов.
  • HTML-шаблон пользовательской страницы определяется внутри кода сервера, смешивая внешний и внутренний код.
  • Программирование пользовательской страницы таким образом очень запутанно, и его трудно поддерживать для чего-то более сложного, чем этот пример.

Последние две проблемы можно решить с помощью шаблонизаторов HTML, таких как EJS (http://ejs.co/) и Jade (http://jade-lang.com/). Это позволит вам создать отдельный файл для страницы пользователя, который сервер затем читает и динамически генерирует в соответствии с заданными вами правилами.

Если вы хотите увидеть это в действии, установите EJS с помощью npm install ejs и создайте новый файл user.ejs. Затем мы говорим экспрессу использовать EJS в качестве механизма просмотра, отображать и отвечать этой новой страницей на запросы к ‘/user’:

Это обеспечивает лучшее разделение задач и удобство сопровождения, и с его помощью вы, безусловно, можете создавать небольшие веб-приложения. Однако это не решает проблемы перезагрузки страницы или нагрузки на сервер. Куда мы отправимся отсюда?

Асинхронный JavaScript и XML (AJAX)

AJAX — это подход, использующий набор технологий, в первую очередь объект XMLHttpRequest, для взаимодействия клиента с сервером в режиме реального времени. Хотя сейчас это довольно старый подход, он по-прежнему широко используется во многих веб-приложениях.

С помощью AJAX запросы данных можно выполнять после того, как страница уже загружена, что устраняет необходимость перезагрузки или изменения страницы. Это также означает, что элементы на странице могут быть изменены без необходимости повторного создания всей страницы на стороне сервера, перенося бремя вычислений с сервера на клиент. Он также предоставляет клиенту возможность динамически генерировать страницу самостоятельно в рамках собственного программирования.

Хотя с объектами XMLHttpRequest можно работать напрямую, каждый веб-браузер обрабатывает их немного по-разному. По этой причине настоятельно рекомендуется использовать библиотеку или API, которые упрощают использование при обеспечении совместимости. Популярная внешняя библиотека jQuery поддерживает это (https://jquery.com/), но не предназначена для использования с другими внешними библиотеками, такими как React (https://reactjs.org/). и AngularJS (https://angularjs.org/). Вместо этого я буду использовать Fetch API (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), который не зависит от внешнего интерфейса.

На сервере мы добавим новые маршруты для «/api». Через них клиент сможет запросить у сервера сообщение JSON, а клиент сможет отправить серверу свои собственные сообщения JSON для отображения в режиме реального времени. Во внешнем интерфейсе я написал две функции JavaScript getMsg() и postMsg(), которые запрашивают у сервера сообщение и передают ему сообщение соответственно:

В отличие от предыдущего, клиент фактически не будет полностью переходить на страницу «/api». Вместо этого он откроет соединение с ним и вернет данные на существующую страницу без необходимости перезагрузки или перенаправления.

Чтобы проверить, работает ли он, откройте еще раз http://localhost:4001 и поэкспериментируйте с кнопками…

Идеально! Наш внутренний и внешний интерфейс общаются друг с другом в режиме реального времени, все с одной страницы.

Если вы хотите получить что-то из серверной части с помощью выборки при первой загрузке страницы, имейте в виду, что вы не можете манипулировать какими-либо элементами HTML, пока не завершится загрузка DOM. Если вы хотите запустить getMsg() немедленно, то самый простой способ — добавить больше тегов сценария после тела HTML, которое просто вызывает getMsg() . Таким образом, вы можете имитировать нашу динамическую генерацию страниц ранее, но полностью из внешнего интерфейса.

Хотя AJAX решает множество проблем, он не идеален:

  • Каждый раз, когда делается запрос, клиент должен начинать новый сеанс. Это дорого, если есть много запросов, и может вызвать узкие места в сети.
  • Запросы могут быть инициированы только клиентом. У сервера нет возможности отправить что-то конкретному клиенту самостоятельно («проталкивание сервером»).
  • Чтобы отслеживать сервер на наличие изменений, клиент должен постоянно опрашивать сервер, что создает много дополнительного трафика соединения и не обеспечивает реального ответа в реальном времени.

Хотя AJAX вполне приемлем для многих случаев использования, некоторые современные веб-приложения, такие как веб-игры, требуют, чтобы многие запросы эффективно пересылались туда и обратно между сервером и конкретным клиентом. Для этого AJAX не подойдет. Куда мы отправимся отсюда?

Ответ — WebSockets, о которых я расскажу в следующей части. На данный момент я надеюсь, что это дало некоторый контекст относительно того, как внешние интерфейсы (клиенты) и внутренние части (серверы) взаимодействуют друг с другом, а также некоторый синтаксис, чтобы вы могли включить его в свои собственные небольшие проекты.

Если у вас есть вопросы, не стесняйтесь спросить. Если есть какие-либо исправления, которые вы хотели бы внести, не стесняйтесь указывать и на них, так как я все еще учусь.

Источники изображений:
— https://devcode.la/blog/frontend-y-backend/ (просмотрено 28.09.2018)
— https://en.wikipedia .org/wiki/Ajax_(programming) (просмотрено 28.09.2018)