Node js управление браузером
Отладка (debugging) — это процесс выявления и устранения ошибок в программных приложениях, который представляет собой нечто большее, чем просто просто вывод значений переменных. Задача этой статьи состоит в том, чтобы показать способ эффективной отладки приложений на Node.js при помощи последней версии Google Chrome DevTools.
Почему console.log не самый лучший вариант?
Использование console.log для отладки кода обычно погружает разработчика в бесконечный цикл «остановить приложение — добавить console.log — перезапустить приложение». Такой способ отладки не только замедляет разработку приложения, но также загрязняет код за счет нагромождения лишних частей. Наконец, попытка вывести значения переменных наряду с логированием других потенциальных операций может затруднить отладку в тех случаях, когда вы захотите найти проверяемые значения.
Инструменты отладки
Инструменты отладки обладают рядом полезных функций, которых нет у console.log. В частности, они позволяют приостановить выполнение приложения в определенных точках кода, а также проверить и изменить значение переменных во время работы программы.
Настройка Google Chrome для отладки Node.js
В браузере Chrome 57+ функция отладки Node.js включена по умолчанию, поэтому нет необходимости вручную активировать ее в панели Experimental Feature, как это требовалось в старых версиях.
Обновите Google Chrome до последней версии (если вы этого еще не сделали) и убедитесь, что используете Node.js 6.4+.
Чтобы начать отладку, запустите приложение Node.js с помощью флага — inspect.
Затем можете проигнорировать URL-адрес, начинающийся с «chrome-devtools: //», который отобразится в терминале, а вместо него перейдите по адресу «about: inspect» в Google Chrome.
Наконец, нажмите «Open dedicated DevTools for Node» («Открыть специальный набор инструментов DevTools для отладки Node»), чтобы начать отладку кода своего приложения.
Если этих средств вам мало, посмотрите, официальную документацию по отладке приложений на Node.js , в которой содержится подробный список всех функций инструментов разработчика и его браузерных альтернатив.
Chrome DevTools в действии
Во второй части этой статьи я хочу продемонстрировать Chrome DevTools в действии на примере отладки следующего приложения на Express.
Это код простейшего приложения на Express, оригинал которого можно посмотреть на github.
Давайте запустим его с флагом — inspect и откроем специальный инструмент браузера Chrome отладки Node по инструкции, описанной выше.
На этом этапе у вас будет доступ ко всем функциям, с которыми вы, возможно, уже знакомы: контрольные точки (breakpoints), карта привязки к исходному коду (source map), проверка снимка кучи (heap snapshot), профилирование, горячая замена переменных JavaScript (hot-swapping) и так далее.
Для иллюстрации обратимся к картинке ниже, на котором показаны контрольные точки (breakpoints) для того, чтобы остановить выполнение программы и произвести «горячую замену» значений переменных.
Чем еще удобен Chrome в качестве инструмента для отладки, так это тем, что он позволяет производить отладку не только клиентской, но и серверной части JavaScript-приложения, и всё это с помощью одного и того же интерфейса 🚀.
Если у вас остались какие-либо вопросы или предложения по этой теме, пожалуйста, пишите автору статьи-оригинала в Twitter по адресу @JacopoDaeli.
Это третья статья в цикле про создание и использование скриптов для веб-скрейпинга при помощи Node.js:
В первой статье разбирались базовые аспекты веб-скрейпинга, такие как получение и парсинг страниц, рекурсивный проход по ссылкам и организация очереди запросов. Во второй статье разбирались анализ сайта, работающего через Ajax, тонкая настройка очереди запросов и обработка некоторых серверных ошибок.
Также во второй статье затрагивалась тема инициализации сессий, но, там речь шла о предельно простом случае, когда достаточно выполнить один дополнительный запрос и сохранить куки.
В этой статье разбирается более сложный случай – инициализация сессий с авторизацией по логину и паролю и с преодолением довольно изощрённой защиты от ботов. Как обычно, на примере реальной (и весьма популярной среди скрейперов) задачи.
В большинстве случаев защита от ботов на сайте направлена не против скрейперов, а против таких вещей, как мошенничество, накрутки или спам в комментариях. Однако это всегда лишний повод задуматься о легальности и этичности скрейпинга именно этого сайта. В этой статье для примера выбран сайт, про который хорошо известно, что его владельцы нормально относятся к скрейпингу (хотя и предпочитают, чтобы он выполнялся через специальный API). Простые правила: если у сайта есть открытый API, значит его владельцы рады скрейперам, а если сайт большой и ультрапосещаемый, нагрузка от скрейпинга в обход API его особо не побеспокоит.
В прошлых статьях целью было показать весь процесс создания и использования скрипта от постановки задачи и до получения конечного результата. В этой статье большая часть аспектов веб-скрейпинга обходится стороной, а вместо этого показывается многообразие подходов к решению одной, довольно узкой задачи. Различные методы и инструменты, их плюсы и минусы, субъективные оценки, примеры кода, вот это вот всё.
Постановка задачи
На этот раз заказчик – другой веб-скрейпер, которому понадобилась помощь коллеги. Он хочет получить (для своего заказчика) данные с известного сайта Amazon. Некоторые из нужных ему данных отдаются только авторизованным пользователям. Разумеется, у заказчика есть аккаунт на Amazon, но проблема в том, что на этом сайте реализована защита от автоматической авторизации. Заказчику нужен модуль на Node.js, который эту защиту проходит. Естественно, речь идёт об инструменте для автоматической авторизации своим аккаунтом под свою ответственность, а не о взломе чужого аккаунта, например.
Например, вот такой код должен выводить адрес электронной почты, доступный только авторизованным пользователям Amazon:
Соответственно заказчику нужен модуль, который получает на вход логин и пароль от аккаунта, а на выходе даёт нужные куки. Что-то вроде этого:
Заказчик будет использовать этот модуль в собственном скрипте для веб-скрейпинга Amazon. Может быть даже прикрутит к собственному фреймворку для скрейпинга. Нам это не принципиально.
Прежде чем переходить к анализу интерфейса авторизации на сайте Amazon стоит отметить один важный момент. Дело в том, что этот сайт работает с деньгами. Его постоянно атакуют злоумышленники, и интересует их обычно отнюдь не получение легальных данных в обход API, как нашего заказчика. Не удивительно, что защитные механизмы этого сайта постоянно совершенствуются. Я ещё помню времена, когда автоматическая авторизация на Amazon осуществлялась одним POST-запросом. Это было задолго до появления Node.js (я тогда скрейпил на Perl). Потом там постепенно добавились такие вещи, как переадресации, скрытые поля форм, одноразовые адреса и тому подобное. В сети до сих пор можно найти примеры авторизации на Amazon (при помощи, например, PHP Curl), в которых реализуется примерно следующий алгоритм:
- Получаем страницу с одноразовой ссылкой на страницу с формой логина;
- Сохраняем куки (которые подходят именно к этой одноразовой ссылке);
- Парсим страницу и получаем нужную ссылку;
- Делаем запрос по этой ссылке (используя сохранённые куки) и получаем страницу;
- Сохраняем куки (они уже другие, да);
- Парсим страницу и получаем значения всех скрытых полей формы логина;
- Добавляем поля электронной почты и пароля;
- Имитируем POST-запрос из формы (используя последние сохранённые куки);
- Получаем ответ с кодом 302 и адресом в заголовке Location;
- Сохраняем куки (третий вариант уже)
- Получаем страницу по адресу из Location (снова используя куки)
- Наконец-то получаем те куки, которые нам нужны, и используем их для авторизованных запросов.
Опытные скрейперы могут заметить, что этот алгоритм – простой. Такая задача может заставить поработать два часа там, где заплачено за один, но она вряд ли сорвёт дедлайн.
Трудно сказать, когда и как защита Amazon поменяется снова, но точно можно сказать, что это непременно произойдёт. Поэтому, при рассмотрении данной задачи конкретный рабочий код менее ценен чем понимание соответствующих подходов и инструментов.
Краткий обзор методов
Все методы решения подобных задач можно условно разделить на три категории:
- Имитация браузера: выполнение запросов на основе данных полученных хакерскими методами, такими как анализ трафика, реверс-инжиниринг скриптов и так далее.
- Автоматическое использование браузера. Сюда относится управление из скрипта настоящими браузерами (например, Chrome) через специальный API (например, с помощью Selenium WD), а также использование headless-браузеров (например PhantomJS).
- Использование браузера вручную. Это не обязательно означает полный отказ от автоматизации скрейпинга, но подразумевает, что живой оператор будет видеть реальные страницы и выполнять на них реальные действия через пользовательский интерфейс.
Выбор из этих трёх пунктов – не очевиден и как минимум субъективен. Все три категории имеют свои плюсы и минусы и любая из них позволяет решить нашу задачу, так что рассмотрим их по очереди.
Имитация браузера
Самый главный плюс такого подхода – его универсальность. Если защита проходится стандартной связкой из человека и браузера, то алгоритм её прохождения может быть найден реверс-инжинирингом. Теоретически, исключений из этого правила нет. В мире веб-скрейпинга существуют задачи, которые могут быть решены исключительно реверс-инжинирингом.
Главный минус такого подхода – его неограниченная трудоёмкость. Это путь для сильных духом и не особо ограниченных по времени. В реальной жизни реверс-инжиниринг одного сложного сайта может занять время, за которое можно написать скрипты для скрейпинга тысячи “обычных” сайтов. В теории изготовитель защиты может потратить на неё сколько угодно времени, а его квалификация может потребовать, чтобы реверс-инжинирингом занимался опытный и талантливый хакер. Проще говоря, на определённом уровне сложности заказчику становится выгоднее вместо крутого хакера нанять клерка-копипейстера. Или вообще отказаться от заказа и обойтись без этих данных.
Стоит отметить, что не каждый скрейпер вообще обладает хакерскими навыками или имеет в команде хакера. Встретившись с необходимостью разбираться в скриптах на сайте большинство отказывается от заказа или выбирает метод из другой категории. Ну, или нанимает другого профессионала.
В случае, когда алгоритм защиты не просматривается при анализе трафика и HTML – стоит начать с других подходов. Если же алгоритм может неожиданно измениться в любой момент (как на Amazon), я рекомендую реверс-инжиниринг рассматривать в последнюю очередь. К тому же мне кажется, что если код прохождения защиты Amazon, полученный реверс-инжинирингом, выложить, например, на Хабр, то можно сразу рядом написать, что этот код устарел – это быстро станет правдой.
В этой статье примеры кода будут описывать другие методы.
Автоматическое использование браузера
Этот подход популярен у начинающих скрейперов настолько, что они переходят к нему каждый раз, как сталкиваются с трудностями при анализе сайта. Профессионалы с жёсткими дедлайнами также любят этот подход.
Главный минус этого подхода – вы запускаете чужой код у себя на компьютере. Этот код может, например, содержать дополнительную защиту от автоматизации самого разного типа от детекторов headless-браузеров и до интеллектуального анализа поведения пользователей. Конечно, можно использовать, например, proxy-сервер, подменяющий скрипт с детектором, но это потребует того же самого реверс-инжиниринга, а тогда вообще непонятно зачем возиться с браузерами.
(Примечание: пример технологии анализа поведения пользователя можно посмотреть на сайте AreYouaHuman, а про детекторы headless-браузеров можно больше узнать из отличной презентации, ссылку на которую kirill3333 оставил в комментарии к позапрошлой статье.)
Ещё один минус этого подхода – браузеры потребляют намного больше ресурсов, чем обычные скрейперские скрипты. Для скрейпинга тысяч (а тем более – миллионов) страниц это плохая идея. Наш заказчик хочет модуль, код которого будет выполняться один раз и отправлять всего несколько запросов, так что нам о ресурсах можно не беспокоиться.
Для автоматического использования браузера из скрипта на Node.JS есть много популярных инструментов. Тут я кратко прохожусь по основным (если я кого-то зря забыл – подскажите в комментариях):
Selenium WD – самый известный и популярный инструмент для автоматического использования браузера. Не нуждается в дополнительном представлении. В сети есть масса примеров и советов. Любому, кто хотя бы подумывает профессионально заняться скрейпингом, стоит попробовать Selenium WD.
К сожалению, для решения нашей задачи Selenium WD плохо подходит. Чтобы с ним работать понадобится установить и настроить Java, сам Selenium WD (приложение на Java), браузер, драйвер браузера и модуль для доступа к Selenium WD из выбранного языка программирования (в нашем случае – из Node.js). Это не самый простой путь, учитывая, что нашему заказчику нужен простой модуль на Node.js, работающий “из коробки” (ну, в крайнем случае требующий что-то вроде ' npm install ').
PhantomJS – headless-браузер на движке WebKit. Он запускает сайты в реальном браузере, только не показывает пользователю страниц, а вместо пользовательского интерфейса использует скрипты на Javascript. Браузер в PhantomJS настолько полноценный, что для него даже есть драйвер для Selenium WD и эта связка отлично работает.
С точки зрения нашей задачи главное, что нужно знать о PhantomJS это то, что хоть он и использует тот же язык Javascript что и Node.js, но это НЕ Node.js. Похож, но не то. Нельзя сделать модуль на Node.js, который бы непосредственно использовал PhantomJS. Можно сделать отдельный скрипт на PhantomJS, а для него сделать модуль-обёртку, который будет запускать отдельный процесс и получать его данные через stdout . В простейшем случае это выглядит так:
Чтобы не возиться с stdout и работать через удобный интерфейс имеет смысл использовать одну из готовых (и тщательно кем-то уже протестированных) обёрток над PhantomJS.
SlimerJS – грубо говоря это тот же PhantomJS, только не на WebKit, а на Gecko. В нашем случае важно, что SlimerJS поддерживается меньшим количеством обёрток чем PhantomJS.
CasperJS – самая известная Node.js-обёртка над PhantomJS и SlimerJS. О том, почему CasperJS лучше чем голый PhantomJS хорошо написано, например, в этой статье (на английском). А вот в этой статье (тоже на английском) можно посмотреть пример прохождения авторизации на Amazon при помощи CasperJS. Вполне рабочее решение, но это не лучший вариант (оцените, хотя бы, объём кода в примере). Я рекомендую вместо CasperJS обратить внимание на следующий пункт списка:
Horseman.js – очень хорошая обёртка над PhantomJS. Идеальный вариант для написания модулей вроде нашего. Не требует никаких сложных действий по инсталляции и настройке. Достаточно в нашем модуле добавить в зависимости phantomjs-prebuilt и node-horseman и всё. Интерфейс у Horseman.js предельно лаконичный, гибкий и лёгкий для чтения. Вот так будет выглядеть рабочий код нашего модуля, написанный с использованием Horseman.js:
Такой код можно читать не глядя в документацию. И он работает.
NW – ещё один управляемый браузер (бывший node-webkit). Позволяет управлять движком Blink из скриптов на Node.js. Основное предназначение – создание десктопных приложений с использованием веб-технологий, но может работать и как headless. На NW можно делать полноценные приложения для скрейпинга. Например, такие, как вот в этой статье от vmb. Такие инструменты, как NW, особенно хороши, когда заказчик боится командной строки и хочет окошко с кнопочками. В нашем случае NW не лучший выбор.
Electron – ещё один инструмент для создания десктопных приложений на базе веб-технологий. По сути это молодой и перспективный конкурент NW и с его помощью также можно делать приложения для скрейпинга с отличной индикацией. Кроме того, Electron легко можно использовать в качестве headless-браузера, но подключать его в наш модуль лучше не напрямую, а через обёртку.
В принципе тут всё то же самое, что и в случае с Horseman.js. Под капотом Electron вместо PhantomJS, но это в глаза не бросается.
Chimera – обычный модуль для Node.js с минимумом зависимостей (фактически только request ). Он позволяет загрузить страницу, выполнить скрипт в её контексте и обработать его результат в контексте Node.js. Среди тех, кто пришёл в скрейпинг из фронтенда, встречаются любители этого модуля, но на мой взгляд он слишком минималистичен. По крайней мере, если заказчик упрётся и потребует модуль без прилагающегося к нему браузерного движка, то можно использовать не Chimera, а следующий вариант:
ZombieJS – этот модуль часто позиционируется как аналог PhantomJS, который можно запускать прямо из Node.js. Никаких браузерных движков ZombieJS не использует, обходясь такими привычными инструментами, как request , jsdom или ws . По сравнению с Horseman.js код на ZombieJS выглядит громоздким, но после Chimera это образец удобства и лаконичности:
К явным минусам ZombieJS можно отнести плохую документацию. Раньше она была хорошая, но потом разработчик её сильно изменил в худшую сторону. Не буду строить конспирологических теорий о том, зачем он это сделал, но вот вам пара ссылок, по которым с ZombieJS можно разобраться: примеры и API.
Интересно, что PhantomJS, Electron и ZombieJS многими сайтами воспринимаются по-разному, так что один инструмент проходит защиту, а другой – блокируется. Это серьёзный повод быть готовым воспользоваться любым из этих трёх инструментов. Хотя, конечно, такие сложные случаи встречаются редко. С сайтом Amazon, например, работают все три скрипта. Ну… пока работают.
Использование браузера вручную
Может показаться, что этот пункт тут приводится ради прикола, однако это не так. Бывают ситуации, когда такой подход не просто оправдан, но и оптимален. Например, когда требуется один раз выполнить сложное для автоматизации действие, а потом очень много раз автоматически выполнять что-то простое. Например, авторизоваться на Amazon, а потом долго скрейпить его.
Главный минус такого подхода – необходимость в живом пользователе для каждого запуска скрипта. То есть нельзя просто стартовать скрейпинг по cron , нужно чтобы кто-то смотрел на страницы и что-то с ними делал.
Самый простой способ добавить к своему скрипту использование браузера вручную – это написание инструкции для пользователя. Понятный текст, объясняющий, например, как взять куки из браузера и поместить в текст скрипта – это та же программа, только не для компьютера, а для человека. Многие программисты умеют писать такие программы хорошо, а многие заказчики легко идут на такой компромисс чтобы сэкономить время и деньги. К сожалению, нашему заказчику нужен модуль, не требующий пользовательских инструкций.
Ещё один способ – написать собственный браузер, который будет запускаться только ради авторизации на Amazon, а потом закрываться. Например, на основе Electron. Это не так уж и сложно сделать. Если в нашем скрипте на Nightmare внести небольшое изменение, то скрипт будет показывать страницы, с которыми работает. Пользователь будет видеть, как скрипт заполняет поля формы и отправляет её. Нужно просто инициализировать Nightmare с дополнительным параметром. Вот так:
Например, так можно увидеть, что сайт начал запрашивать капчу, что происходит не так уж редко. Более того, пользователь может ввести капчу прямо в окне Electron и всё будет работать. Только время ожидания в скрипте стоит поставить побольше, а то пользователь может не успеть. Вообще, можно убрать автоматическое заполнение полей формы и предоставить это пользователю. Тогда можно будет не хранить пароль в тексте скрипта. Более того, тогда можно будет в разные моменты времени скрейпить от имени разных пользователей.
С другой стороны, Nightmare можно научить распознавать запрос капчи и проходить её при помощи таких сервисов, как Death by Captcha, но у нас в задаче такого требования нет.
Заключение
Задача из этой статьи намного сложнее чем всё то, что обычно делают веб-скрейперы в реальной жизни. Однако на современных биржах фриланса часто бывает так, что битву за заказ выигрывает тот, кто первым заявляет, что способен его выполнить быстро и хорошо. В результате очень выгодно иметь способность брать заказы практически не глядя и не попадать в неприятности с сорванными дедлайнами, проваленными соглашениями, испорченной репутацией и понизившимся рейтингом. Поэтому, даже если скрейпер целыми днями делает элементарные скрипты для получения данных с простых сайтов, полезно быть готовым столкнуться со сложной защитой и не испугаться. Если хотя бы поверхностно освоить подходы, описанные в этой статье (и в двух предыдущих), то процент “нерешаемых” заказов будет пренебрежительно мал.
В ближайшее время я планирую написать о скрейпинге регулярно обновляющихся данных, скрейпинге данных больших объёмов, терминологии скрейпинга, а также о моральных и правовых аспектах скрейпинга. Советы и рекомендации по выбору тем особо приветствуются.
Часто в ходе нашей работы мы сталкиваемся с необходимостью снова и снова повторять действия пользователя, чтобы убедиться, что по мере внесения изменений на наш сайт ничего не сломалось. Для систематического и удобного решения этой задачи критически важными являются библиотеки, позволяющие создавать такие тесты. Познакомьтесь с безголовыми браузерами! Это инструменты командной строки, предоставляющие возможность программно создавать сценарии взаимодействия пользователя на сайте с последующей фиксацией их результатов для использования в тестах.
Многие из нас годами пользуются PhantomJS, CasperJS и другими инструментами. Но, как часто бывает с любовью, наши сердца могут быть завещаны другому. Начиная с Chrome 59 (60 для пользователей Windows), Chrome поставляется с собственным безголовым браузером. И хотя в настоящее время он не имеет поддержки для Selenium, он использует Chromium и движок Blink, то есть имитирует актуальный пользовательский интерфейс в Chrome.
Как всегда, код этой статьи можно найти в репозитории GitHub.
Запуск безголового Chrome из командной строки относительно прост. На Mac вы можете установить алиас для Chrome и выполнить его с помощью параметра командной строки --headless :
На Linux всё ещё проще:
Вы также можете взаимодействовать с запрашиваемой страницей, например, для вывода document.body.innerHTML в stdout:
Если вас интересно большее количество возможностей, полный список параметров можно найти здесь.
Однако данная статья не о запуске безголового Chrome в командной строке, а об его запуске в Node.js. Для этого нам понадобятся следующие модули:
- chrome-remote-interface: JavaScript API, обеспечивающее простую абстракцию для команд и уведомлений
- chrome-launcher: позволяет нам запускать Chrome из Node.js кроссплаторменно
Затем мы можем настроить нашу среду. Предполагается, что на вашем компьютере установлены Node.js и npm. Если это не так, ознакомьтесь с нашим учебным пособием.
После этого мы хотим создать сессию безголового Chrome. Начнем с создания файла index.js в нашей папке проекта:
Во-первых, мы рекваирим наши зависимости, а затем создаем самовызывающуюся функцию, которая будет порождать экземпляр сессии Chrome. Обратите внимание, что флаг --disable-gpu требуется на момент написания этой статьи, но может оказаться не нужен, когда вы будете читать это, поскольку это всего лишь обходной путь (в соответствии с рекомендацией Google). Мы будем использовать async / await , чтобы гарантировать, что наше приложение ожидает запуск безголового браузера перед выполнением следующих шагов.
Примечание: Мы будем работать с функциями, требующим окончания определенных действий перед переходом к последующим шагам. Например, отрисовки страницы или завершения ряда взаимодействий. Многие из этих шагов не блокирующие, поэтому нам нужно использовать промисы для приостановки исполнения. Подробнее об async -функциях можно прочитать на Mozilla Developer Network или на SitePoint.
Далее нам нужно выявить области (domains), которые нам нужны для нашего тестирования:
Наиболее важный здесь объект Page : мы будем использовать его для доступа к содержимому пользовательского интерфейса. С его помощью мы укажем, куда мы переходим, с какими элементами взаимодействуем, где мы запускаем наши скрипты.
После того, как мы инициализировали нашу сессию и определили наши области, мы можем начать навигацию по сайту. Для выбора точки входа мы используем домен Page , который мы включили выше, и переходим к:
Этот код загрузит страницу. Затем, используя метод loadEventFired , мы определяем шаги, которые хотим осуществить в нашем приложении для воспроизведения сценария взаимодействия пользователя. В этом примере мы просто получаем содержимое первого абзаца.
Если вы запустите скрипт с помощью node index.js , вы увидите что-то вроде этого:
Мы так же легко можем заменить код в script1 на любой другой, например, на нажимающий на ссылки, заполняющий поля форм или запускающий серию взаимодействий с помощью query -селекторов. Каждый шаг может быть сохранен в конфигурационном JSON-файле и загружен в ваши скрипты на Node.js для выполнения последовательно. Результаты этих сценариев могут быть проверены с использованием платформы тестирования, такой как Mocha, что позволяет удостовериться, что полученные значения соответствуют требованиям UI / UX.
В дополнение к вашим тестовым сценариям вы, вероятно, захотите сделать скриншоты своих страниц при навигации по сайту. К счастью, выбранная область (Page) имеет функцию captureScreenshot , которая именно этим и занимается.
Флаг fromSurface - еще один флаг, требуемый для поддержки кроссплатформенности на момент написания этой статьи и может не понадобиться в будущем.
Запустите скрипт с помощью node index.js и вы получите примерно такой результат:
Если вы пишете автоматические тесты, вы должны начать использовать безголовый Chrome. Хотя он по-прежнему не полностью интегрирован с такими инструментами, как Selenium, преимущество имитации движка рендеринга Chrome не следует недооценивать. Это лучший способ полностью воссоздать пользовательский опыт.
Node.js с Express — это популярный дуэт, используемый многими приложениями во всем мире. Данный урок познакомит вас с функциональностью этих инструментов на примере сборки простого веб-сервера.
Создаваемый сервер будет обслуживать HTML-страницу, доступную другим людям. К концу статьи вы усвоите базовые знания о:
- Node.js;
- Express;
- npm;
- создании маршрутов Express;
- обслуживании HTML;
- настройке статических ресурсов Express.
Совет: не копируйте код урока, а напишите его сами. Это позволит вам лучше его понять и усвоить.
Первым шагом будет создать пустой каталог для проекта. Это можно сделать обычным способом либо из терминала с помощью следующих команд:
После создания проекта нужно его инициализировать:
Эта команда создает файл package.json и инициализирует его с предустановленными значениями. Если вы захотите сами заполнить его поля, удалите флаг -y и следуйте инструкциям.
После инициализации проекта Node.js мы переходим к следующему шагу — добавлению Express. Установка пакетов в Node.js выполняется командой npm install packageName .
Для добавления последней стабильной версии Express выполните:
После установки Express файл package.json будет выглядеть так:
Express перечислен среди dependencies , значит, он установился успешно. Переходим к третьему шагу — созданию сервера.
Прежде чем продолжать, нужно создать для сервера JS-файл. Выполните в терминале следующую команду:
Теперь откройте этот файл и пропишите в нем:
Что эти строки делают?
- Первая импортирует Express в проект, чтобы его можно было использовать. При каждом добавлении в проект пакета необходимо импортировать его туда, где он будет использоваться.
- Вторая строка вызывает функцию express , которая создает новое приложение, после чего присваивает результат константе app .
Создание маршрутов и прослушивание порта
Пропишите в файле следующий код:
Разберем его согласно приведенной ранее структуре:
Следовательно, когда пользователь выполняет запрос GET к домашней странице, т.е. localhost:3333 , вызывается стрелочная функция и отображается фраза “Hello WWW!”
Последним шагом подготовки сервера к работе будет настройка слушателя. Понадобится указать для приложения конкретный порт. Напишите нижеприведенный код в конец JS-файла.
Чтобы иметь возможность запускать сервер, вам нужно будет вызывать метод listen . При этом вы также можете изменить номер порта (3333) на любой другой.
Доступ к приложению в браузере
Для запуска приложения выполните в терминале node index.js . Имейте в виду, что index.js — это произвольное имя, которое я выбрал для данного урока, так что можете назвать его app.js или как-угодно иначе.
Вы отлично справились с настройкой веб-сервера Node.js + Express. В следующем разделе мы настроим статическое содержимое, а именно JavaScript, CSS, HTML, изображения и т.д.
Наше приложение пока что выглядит не очень. Почему бы не добавить ему структуру и стилизацию? Но куда все это нужно добавлять?
В этом разделе вы узнаете, как настраивать и передавать статические ресурсы, такие как HTML, JavaScript, CSS и изображения.
Импорт модуля path
Первым делом нужно импортировать в приложение модуль path . Устанавливать ничего не нужно, потому что path предустановлен в Node изначально.
Пропишите в начале файла эту строку:
Зачем вообще этот модуль? Он позволяет генерировать абсолютные пути, которые необходимы для передачи статических файлов. Добавьте следующую строку в приложение перед определением маршрутов:
path.join получает два аргумента:
- Текущую рабочую директорию (cwd).
- Вторую директорию, которую нужно объединить с cwd.
В качестве упражнения попробуйте вывести в консоль path.join(__dirname, 'public') и посмотрите, что получится.
На данный момент сервер должен выглядеть так:
Создание каталога public и добавление ресурсов
Создайте каталог и перейдите в него с помощью следующих команд:
Теперь создадим пустые файлы, куда затем добавим HTML, CSS и JavaScript. Выполните в терминале следующие команды:
То же и с styles.css . Для проверки его работоспособности мы установим цвет фона на синий:
В завершении нужно написать HTML, чтобы отображать все это на домашней странице. Откройте index.js и добавьте следующий HTML-код:
Теперь остается всего один шаг.
Мы почти закончили. Осталось только обработать HTML-код. Для этого нужно перейти в файл index.js и прописать в нем следующее:
Если вы уже ранее работали с Node.js и Express, то можете спросить: “Что здесь делает метод sendFile и почему мы не используем render ?” Метод render мы использовать не можем, так как не задействуем никакой движок (например, Pug, EJS и т.д.). Следовательно, когда кто-либо обращается к домашней странице, мы отправляем назад HTML-файл.
Здравствуйте, не могу собрать мозаику букваря, по взаимодействию браузера и node.js.
Как обратиться из браузера (html страница с кодом JavaScript), к коду серверной части Node.js?
Подскажите, пож, простейший пример чтения в браузере, в HTML коде с помощью JavaScript текстового файла с диска (средствами Node.js) и вывода результата в окне браузера? Как это делается в perl или php с легкостью.
console.log("Hello from JavaScript!");
И пишет что вы увидите "я так понимаю в браузере, не в консоле же. " мозольную строчку "Hello from JavaScript!". Это как это у него получилось? У меня - ошибка в отладчике "Failed to load resource: the server responded with a status of 404 (Not Found)".
Дальше в статье идет про npm и др.
Node.js у меня установлен, в Visual Studio Code в консоле отдельно "console.log("Hello from JavaScript!");" естественно работает.
Взаимодействие Node with Angular
Объяснить, как angular взаимодействует node.
Подскажите букварь по GLSL
Собственно сабж. Помогите пожалуйста. А то все что нарыл в инете не пашет. Вот здесь букварь по.
Вывести частотный букварь предложения
Пользователь вводит предложение или ряд цифр.Вывести его частотный букварь(какой символ сколько раз.
Сма LG F1081 TD, 308PNUR5S774, Прошу букварь
Всем добрейшего и удачного! После замены прессостата, ошибка РЕ продолжала появляться и приобрела.
решения 3!
1) генерация html страницы на стороне сервера (самое простое решение)
2) статик-страница которая через ajax из javascript браузера забирает json файлик с севера. (самый "современный" подход)
3) общение через сокеты (чаты часто используют)
эта хабр-статья - плохая! (для новичка). (количество "динозавров" зашкаливает, мне стало скучно на 2й странице)
самый простой код:
не путайте с php/perl! здесь методика другая! программа генерирует СВОЙ веб-сервер.
"Динозавров" я фильтрую. Спасибо, попробовал Ваш сервер. Но почему-то у меня он не запускается. Я до этого пробовал несколько кодов server.js. И у меня запускается только этот код:
И на этом коде, обращаясь к http://127.0.0.1:8080 (или к своему локальному домену), я получаю хабровский hello-файл и в консоле отладчика вижу "Hello from JavaScript!". Все работает.
Как этим воспользоваться? Как теперь в браузер вернуть эту строку? Не в консоль.
Не понимаю всю цепочку: браузер - чтение (запись) фала с диска - вывод результата в браузер. Простой бы примерчик все разъяснил бы. Читал что с MySql твориться.
попробую "на пальцах".
через http вы запускаете свой сервер на порту 8080.
после чего к нему можно обращаться через http://127.0.0.1:8080
(ПХП использовал "плагин" привязанный к апачи или к nginx)
req - параметры запроса. Их УЙМА! если не лень попробуйте console.log(req). Но среди них есть и куки, и /asdf, и даже отсылаемые на сервер файлы
res - то куда клиенту отправляем "ответ".
модуль node-static (кстати его надо установить через npm - вроде не из "стандартных" - я им не пользуюсь) занимается отправкой файлов на любой запрос
>> npm i node-static
еще можешь попробовать для отправки текста вместо файла
Как работать с node-static не понял, сорри, так как там нет готовых примеров, только "отрывки", которые не всегда понятно как применять.
Нашел вот такой код, который записывает в текстовый файл readme.txt в конец текста фразу "Copyrighted by Me". Скрипт прекрасно работает в VSC. Вот его код:
Сохраняем скрипт в "index.js". Идем далее, чтобы запустить этот скрипт из браузера, как написано в хабр-статье (упомянутой выше), браузер не понимает метод "require", поэтому начинаем применять бандлер. Установил вебпак:
Запускаем webpack и пытаемся перевести код с непонятным браузеру методом "require" в понятный браузеру код, записанный в файл, например "bundler.js". Запускаем в командпромпт:
И получаем ошибку:
Что сделать, чтобы получить бандл скрипт, и чтобы получить доступ к скрипту из браузера?
Я всего лишь хочу небольшой готовый пример:
1. Открываю в браузере страничку HTML, там ссылка на javascript файл (или код javascript внутри html);
2. Этот код читает с диска файл "readme.txt" (по ходу может туда дописать что-нибудь). Вот этот последний код по записи строки 'Copyrighted by Me', который я дал, прекрасно подойдет;
3. Прочитанную строчку возвращает в браузер и мы видим текст из файла "readme.txt" в окне браузера, например: "эта строчка из текстового фала readme.txt".
Возможно ли такое с помощью node.js? На perl/php такое делается легко. на ноде куча примеров без взаимодействия с браузером, но я хочу понять можно ли сделать такое простое взаимодействие: браузер - node.js - браузер.
Извините, за непонимание ).
Добавлено через 5 минут
Пример запуска сервера я понял, пример с чтением файла в окно браузера может быть без запуска сервера, я на апаче запускаюсь.
1. Открываю в браузере страничку HTML, там ссылка на javascript файл (или код javascript внутри html);
2. Этот код читает с диска файл "readme.txt"
javascript на стороне браузера не может просто так прочитать файл. Вы хотите чтобы при переходе на ссылку, просто отображалось содержимое файла readme.txt.?
Поэтому мы все тут собрались
Я считаю, что node.js можно использовать как perl или php для работы в браузере с фалами и др. Дайте пример?
multidem, ни perl, ни php, не могут в браузере работать с файлами. Они - серверные языки, и все что могут делать с бразуером, это отправлять ответы на его вопросы. Дайте пример из php
javascript на стороне браузера не может просто так прочитать файл. Вы хотите чтобы при переходе на ссылку, просто отображалось содержимое файла readme.txt.?
Похоже здесь у нас "перебежчик" из РНР!
попробую еще раз:
в РНР при выборе my.com/1.php сервер искал файл 1.php, выполнял его в "плагине" апачи/нгинкса и выгружал из памяти.
в Ноде все немного по другому! Вы запускаете НЕУБИВАЕМЫЙ("зацикленный") сервер, который вечно в памяти крутит вашу програмку! и обрабатывает по очереди все входящие в него запросы от клиента.
Хотите обработать submit-кнопку клиента - отсылаете серверу запрос на определенный адрес вроде my.com/form или my.com:3000/form или 127.0.0.1:3000/form
сервер отлавливает в параметрах запроса /form и отсылает на отдельную "подпрограммку". Там вы берете другие параметры из шапки и пишете в ваш текстовый файл.
при обработке (например) /info вы читаете ваш текстовый файл "readme" и отдаете его клиенту (возможно предварительно обработав).
Никакой я не перебежчик Я просто пытаюсь понять как это работает на ноде.
Можете дать короткий ГОТОВЫЙ рабочий ZIP пример, как для сервера прислали, это заменит все объяснения!?
Спасибо Вам большое.
Добавлено через 11 минут
ни perl, ни php, не могут в браузере работать с файлами. Они - серверные языки, и все что могут делать с бразуером, это отправлять ответы на его вопросы. Дайте пример из php
Добавлено через 4 минуты
И читается этот readme.txt также легко в браузере и выводиться в окне браузера строка "Это строку необходимо нам записать". Показать пример?
multidem, вам кажется что это так . Все, что между выполняется как php код а выводы echo выводятся в ответ серверу, php код никогда не выполняется на стороне клиента. Сейчас скину как это делается в node.js:
Хотите обработать submit-кнопку клиента - отсылаете серверу запрос на определенный адрес вро.
Можете дать короткий ГОТОВЫЙ рабочий ZIP пример, как для сервера прислали, это заменит все объяснения!?
Это не легко! я express не знаю, а там это в 10-20 строк делается, а мои самоделки слишком сложные для использования (хоть и быстрее express).
Гугли "node js submit example"
. но это для отправки данных из формы для обработки сервером!
если просто надо строку, прописанную в сервере, надо записать при открытии страницы
Спасибо andyj, спасибо MrOnlineCoder! Отвечу Вам, чтобы далее добираться до истины
Я никогда не утверждал, что php выполняется на стороне клиента, с чего Вы взяли?. В моем посте ключевое слово ВЗАИМОДЕЙСТВИЕ, для простоты слова я писал "пример обращения к файлам из браузера", но подразумевается ВЗАИМОДЕЙСТВИЕ клиента и сервера, естественно. В случае perl - это html код - cgi код. В случае php - это html код - php код. Я написал не одно CGI веб приложение по взаимодействию html - perl: обработка формы, работа с файлами, работа с mysql и прекрасно понимаю о чем говорю.
Давно хотел попробовать node.js и прочитав посты в нете что "Node.js создан для программирования серверной части, бла бла бла" ничего другого и подумать не могу, что все что мы делаем на перле и пхп в браузере (с формами, файлами, mysql) можно делать с помощью ноды.
Спасибо также за Ваш пример, но я все равно не понимаю как этим примером воспользоваться? Когда я запускаю его в VSC, я вижу строку, что сервер запущен. Когда я подключаю его к html, браузер затыкается на операторе "require", он его не знает! Я вычитал в нете что нужно использовать бандл, я установил вебпак, но он выдает ошибку при трансляции нодовского кода в код бандл, я писал об этом выше. Поэтому, может подскажешь, как воспользоваться твоим кодом из браузера?
Та же беда, когда я записываю этот код при открытии страницы, браузер затыкается на методе "require".
Про пакет express я читал и видел коды, но по простой причине отсутствия конечного примера, я путаюсь "в трех соснах" и не могу понять как этим воспользоваться.
Читайте также: