aboutsummaryrefslogtreecommitdiff
path: root/files/ru/learn/server-side/express_nodejs/introduction/index.html
blob: 881a3c70d6c6d4dbf847559a6ec54db675d7afa3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
---
title: Express/Node introduction
slug: Learn/Server-side/Express_Nodejs/Introduction
translation_of: Learn/Server-side/Express_Nodejs/Introduction
---
<div>{{NextMenu("Learn/Server-side/Express_Nodejs/development_environment", "Learn/Server-side/Express_Nodejs")}}</div>

<p class="summary">В этой первой статье по Express мы ответим на вопросы "Что такое Node?" и "Что такое Express?", и сделаем обзор того, что делает веб-фреймворк Express таким особенным. <span id="result_box" lang="ru"><span>Мы расскажем об основных функциях и покажем вам некоторые из основных строительных блоков приложения Express (хотя на данный момент у вас ещё нет среды разработки, в которой можно её протестировать).</span></span></p>

<table class="learn-box standard-table">
 <tbody>
  <tr>
   <th scope="row">Предварительные знания:</th>
   <td><span id="result_box" lang="ru"><span>Базовая компьютерная грамотность.</span> <span>Общее понимание </span></span><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/First_steps">серверного программирования веб-сайтов </a><span lang="ru"><span>и, в частности, механики </span></span><a href="/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview">клиент-серверного взаимодействия на веб-сайтах</a>.</td>
  </tr>
  <tr>
   <th scope="row">Цель:</th>
   <td>Ознакомить вас с фреймворком <span id="result_box" lang="ru"><span>Express и как он вписывается в среду  Node, какие функции он предоставляет, и основные строительные блоки приложения Express.</span></span></td>
  </tr>
 </tbody>
</table>

<h2 id="Что_такое_Express_и_Node">Что такое Express и Node?</h2>

<p><a href="https://nodejs.org/">Node</a> (или более формально<em> Node.js</em>) <span id="result_box" lang="ru"><span>- кросплатформенная среда исполнения с открытым исходным кодом, которая позволяет разработчикам создавать всевозможные серверные инструменты и приложения  используя язык </span></span><a href="/en-US/docs/Glossary/JavaScript">JavaScript</a><span lang="ru"><span>. Среда исполнения предназначена для использования вне контекста браузера </span></span>(т.е. <span id="result_box" lang="ru"><span>выполняется непосредственно на компьютере или на серверной ОС)</span></span>. <span id="result_box" lang="ru"><span>Таким образом, среда исключает API-интерфейсы JavaScript для браузера и добавляет поддержку более традиционных OS API-интерфейсов</span></span><span lang="ru"><span>, включая библиотеки HTTP и файловых систем.</span></span></p>

<p>С точки зрения веб-серверной разработки Node имеет ряд преимуществ:</p>

<ul>
 <li>Отличная производительность! Node <span id="result_box" lang="ru"><span>был разработан для оптимизации пропускной способности и масштабируемости в веб-приложениях и очень хорошо справляется со многими распространёнными проблемами веб-разработки (например, веб-приложения реального времени).</span></span></li>
 <li><span id="result_box" lang="ru"><span>Код написан на «обычном старом JavaScript», а это означает, что затрачивается меньше времени при написании кода для браузера и веб-сервера связанное с  «переключением технологий» между языками.</span></span></li>
 <li><span id="result_box" lang="ru"><span>JavaScript является относительно новым языком программирования и имеет преимущества от улучшения дизайна языка по сравнению с другими традиционными языками для веб-серверов</span></span> (например, Python, PHP, и т.д.). Многие другие новые и популярные языки компилируются/конвертируются в JavaScript, поэтому вы можете также использовать CoffeeScript, ClosureScript, Scala, LiveScript, etc.</li>
 <li>Менеджер пакетов Node (NPM) <span id="result_box" lang="ru"><span>обеспечивает доступ к сотням тысяч многоразовых пакетов.</span> <span>Он также имеет лучшее в своём классе разрешение зависимостей и может также использоваться для автоматизации большинства инструментов построения.</span></span></li>
 <li>Он портативен, имеет версии для  Microsoft Windows, OS X, Linux, Solaris, FreeBSD, OpenBSD, WebOS, и NonStop OS. Кроме того, он имеет хорошую поддержку среди многих хостинг-провайдеров, <span id="result_box" lang="ru"><span>которые часто предоставляют конкретную инфраструктуру и документацию для размещения сайтов, работающих на Node.</span></span></li>
 <li><span id="result_box" lang="ru"><span>Он имеет очень активную стороннюю экосистему и сообщество разработчиков, которые всегда готовы помочь.</span></span></li>
</ul>

<p><span lang="ru"><span>Вы можете использовать Node.js для создания простого веб сервера используя пакет Node HTTP. </span></span></p>

<h3 id="Hello_Node.js">Hello Node.js</h3>

<p>Следующий пример создаёт веб сервер который обрабатывает любой HTTP запрос на <span id="result_box" lang="ru"><span>URL <code>http://127.0.0.1:8000/</code> </span></span>— когда запрос будет получен, скрипт ответит строкой "Hello World". Если вы уже установили node, можете, следуя шагам инструкции попробовать пример:</p>

<ol>
 <li>Откройте терминал (в Windows окно командной строки)</li>
 <li>Создайте папку, куда вы хотите сохранить программу, к примеру <code>test-node</code> и перейдите в неё с помощью следующей команды:</li>
</ol>

<pre class="notranslate"><code>cd test-node</code></pre>

<ol start="3">
 <li>Используя любимый текстовый редактор, создайте файл <code>hello.js</code> и вставьте в него код:</li>
</ol>

<pre class="brush: js notranslate">// Загружаем HTTP модуль
const http = require("http");

const hostname = "127.0.0.1";
const port = 8000;

// Создаём HTTP-сервер
const server = http.createServer((req, res) =&gt; {

   // Устанавливаем HTTP-заголовок ответа с HTTP статусом и Content type
   res.writeHead(200, {'Content-Type': 'text/plain'});

   // Отсылаем тело ответа "Hello World"
   res.end('Hello World\n');
});

// Выводим лог как только сервер будет запущен
server.listen(port, hostname, () =&gt; {
   console.log(`Server running at http://${hostname}:${port}/`);
})
</pre>

<ol start="4">
 <li>Сохраните файл в папку, созданную выше.</li>
 <li>Вернитесь в терминал и выполните следующую команду:</li>
</ol>

<pre class="notranslate"><code>node hello.js</code></pre>

<p>В итоге, перейдите по ссылке <code>http://localhost:8000</code> в вашем браузере; вы должны увидеть текст "<strong>Hello World</strong>" в верху слева на чистой странице.</p>

<h2 id="Веб_фреймворк">Веб фреймворк</h2>

<p>Другие общие для веб-программирования задачи не поддерживаются на прямую Node. Если вы хотите добавить специфичную поддержку различных HTTP методов (например <code>GET</code><code>POST</code><code>DELETE</code>, и т.д.) по разному для разных URL путей ("routes"), отдачу статических файлов, или использовать шаблоны для создания динамических ответов, вам нужно написать код самим, или можете отказаться от изобретения колеса и использовать фреймворк!</p>

<h2 id="Введение_в_Express">Введение в Express</h2>

<p><a href="https://expressjs.com/">Express</a> - самый популярный веб-фреймворк для <em>Node</em>. Он является базовой библиотекой для ряда других популярных <a href="https://expressjs.com/en/resources/frameworks.html">веб-фреймворков Node</a>. Он предоставляет следующие механизмы:</p>

<ul>
 <li>Написание обработчиков для запросов с различными HTTP-методами в разных URL-адресах (маршрутах).</li>
 <li>Интеграцию с механизмами рендеринга «view», для генерации ответов, вставляя данные в шаблоны.</li>
 <li>Установка общих параметров веб-приложения, такие как порт для подключения, и расположение шаблонов, которые используются для отображения ответа.</li>
 <li>«промежуточное ПО» для дополнительной обработки запроса в любой момент в конвейере обработки запросов.</li>
</ul>

<p>В то время как сам express довольно минималистичный, разработчики создали совместимые пакеты промежуточного программного обеспечения для решения практически любой проблемы с веб-разработкой. Существуют библиотеки для работы с куки-файлами, сеансами, входами пользователей, параметрами URL, данными POST, заголовками безопасности и многими другими. Вы можете найти список пакетов промежуточного программного обеспечения, поддерживаемых командой Express в <a href="http://expressjs.com/en/resources/middleware.html">Express Middleware</a> (наряду со списком некоторых популярных пакетов сторонних производителей) .</p>

<div class="note">
<p><strong>Примечание:</strong> Гибкость это палка о двух концах. <span id="result_box" lang="ru"><span>Существуют пакеты промежуточного программного обеспечения (middleware) для решения практически любых проблем или для удовлетворения любых ваших требований, но правильный выбор подходящих пакетов иногда может быть проблемой.</span> <span>Также нет «правильного пути» для структурирования приложения, и многие примеры, которые вы можете найти в Интернете, не являются оптимальными или лишь показывают небольшую часть того, что вам нужно сделать для разработки веб-приложения.</span></span></p>
</div>

<h2 id="Откуда_это_все_взялось">Откуда это все взялось?</h2>

<p>Node первоначально был выпущен только под Linux в 2009. Менеджер пакетов NPM был выпущен в 2010, а поддержка Windows была добавлена в 2012. Текущая LTS-версия Node v12.16.1 , в то время как последний выпуск Node версии 13.11.0. Это короткий экскурс в историю; обратитесь к <a href="https://en.wikipedia.org/wiki/Node.js#History">Википедии</a>, если вы хотите узнать больше).</p>

<p>Express первоначально был выпущен в ноябре 2010 и текущая версия API 4.17.1 вы можете отследить <a href="https://expressjs.com/en/changelog/4x.html">изменения</a> и текущий релиз, и <a href="https://github.com/expressjs/express/blob/master/History.md">GitHub</a> для более детальной информации о релизах.</p>

<h2 id="Насколько_популярен_NodeExpress">Насколько популярен Node/Express?</h2>

<p>Популярность веб-фреймворка важна, поскольку она является индикатором того, будет ли она продолжаться, и какие ресурсы, вероятно, будут доступны с точки зрения документации, дополнительных библиотек и технической поддержки.</p>

<p>Не существует какого-либо доступного и точного измерения популярности серверных фреймворков (хотя сайты, такие как Hot Frameworks, пытаются оценить популярность, используя такие механизмы, как подсчёт количества проектов на GitHub и вопросов на StackOverflow для каждой платформы). Лучший вопрос заключается в том, достаточно ли популярны Node и Express, чтобы избежать проблем с непопулярными платформами. Они продолжают развиваться? Можете ли вы получить помощь, если вам это нужно? Есть ли у вас возможность получить оплачиваемую работу, если вы изучаете Express?</p>

<p>Как только мы посмотрим на список <a href="https://expressjs.com/en/resources/companies-using-express.html">широкоизвестных компаний</a> пользующихся Express, количество разработчиков участвующих в разработке Express, и громадному числу людей, которые занимаются поддержкой Express, то мы с уверенностью скажем -  <em>Express</em> поистине популярный фреймворк!</p>

<h2 id="Является_ли_Express_ограничивающим">Является ли Express ограничивающим?</h2>

<p>Web-фреймворки часто принято делить на "ограничивающие" и "не ограничивающие".</p>

<p>Ограничивающими фреймворки считаются фреймворки, которые следуют "должным" ограничениям при выполнении отдельных задач. Довольно часто они ориентированы на ускоренную разработку <em>в конкретной области</em>  (решение задач определённого типа), поскольку должный подход  к произвольно выбранной задаче бывает не прост для понимания и плохо документирован. При этом они лишаются гибкости при решении задач выходящих за сферу их обычного применения, а так же проявляют тенденцию к ограничению выбора компонентов и подходов своего применения. </p>

<p>Напротив, не ограничивающие фреймворки имеют гораздо меньше ограничений для связи компонентов, что бы достичь цели или ограничений в выборе используемых компонентов. Они облегчают разработчикам использование наиболее подходящих инструментов для выполнения конкретной задачи, но платой за это будет то, что вы самостоятельно должны найти такие компоненты.</p>

<p>Express не ограничивающий. Вы можете вставить в цепочку обработки (middleware) запросов практически любое совместимые промежуточные компоненты, которые вам нравятся. Вы можете структурировать приложение в одном файле или в нескольких, использую любую структуру каталогов. Иногда вы можете чувствовать, что у вас слишком много вариантов!</p>

<h2 id="Как_выглядит_код_Express">Как выглядит код Express?</h2>

<p>В традиционных динамических веб-сайтах, веб-приложение ожидает HTTP-запроса от веб-браузера (или другого клиента). Когда запрос получен, приложение определяет, какое действие необходимо выполнить на основе URL шаблона и, возможно, связанной информации, содержащейся в данных <code>POST</code> или <code>GET</code>. В зависимости от того, что требуется, Express может затем читать или записывать данные из/в базы данных или выполнять другие задачи, в соответствии с полученным запросом. Затем приложение возвращает ответ в веб-браузер, зачастую динамически создавая HTML страницу для отображения браузером, вставляя извлечённые данные в заполнители HTML шаблона.</p>

<p>Express предоставляет методы позволяющие указать, какая функция вызывается для конкретного HTTP запроса (<code>GET</code>, <code>POST</code>, <code>SET</code>, etc.), и URL шаблон ("Route"), а также методы позволяющие указать, какой механизм шаблона ("view") используется, где находятся шаблоны файлов и какой шаблон использовать для вывода ответа. Вы можете использовать Express middleware для добавления поддержки файлов cookies, сеансов, и пользователей, получения <code>POST</code>/<code>GET</code> параметров, и т.д. Вы можете использовать любой механизм базы данных, поддерживаемый Node (Express не определяет поведение, связанное с базой данных).</p>

<p>В следующих разделах объясняются некоторые общие моменты, которые вы увидите при работе с кодом <em>Express</em> and <em>Node</em>.</p>

<h3 id="Helloworld_Express">Helloworld Express</h3>

<p><span class="tlid-translation translation" lang="ru"><span title="">Сначала давайте рассмотрим стандартный пример Express Hello World (мы обсудим каждую часть этого ниже и в следующих разделах).</span></span></p>

<div class="note">
<p><span class="tlid-translation translation" lang="ru"><span title="">Совет: Если у вас уже установлены Node и Express (или если вы устанавливаете их, как показано в следующей статье), вы можете сохранить этот код в файле с именем app.js и запустить его в командной строке, вызвав узел app.js.</span> <span title="">отражения</span><span title="">)</span><span title="">.</span></span></p>
</div>

<pre class="brush: js notranslate">var express = require('express');
var app = express();

<strong>app.get('/', function(req, res) {
  res.send('Hello World!');
});</strong>

app.listen(3000, function() {
  console.log('Example app listening on port 3000!');
});
</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Первые две строки требуют () (импорт) модуля Express и создания приложения Express.</span> <span title="">Этот объект, который традиционно называется app, имеет методы для маршрутизации HTTP-запросов, настройки промежуточного программного обеспечения, рендеринга представлений HTML, регистрации механизма шаблонов и изменения параметров приложения, которые управляют поведением приложения (например, режим среды, чувствительны ли определения маршрута к регистру).</span> <span title="">, и т.д.)</span></span></p>

<p><span class="tlid-translation translation" lang="ru"><span title="">Средняя часть кода (три строки, начинающиеся с app.get) показывает определение маршрута.</span> <span title="">Метод app.get () указывает колбэк-функцию, которая будет вызываться всякий раз, когда есть HTTP-запрос GET с путём ('/') относительно корня сайта.</span> <span title="">Колбэк-функция принимает запрос и объект ответа в качестве аргументов и просто вызывает send () для ответа, чтобы вернуть строку «Hello World!»</span></span></p>

<p><span class="tlid-translation translation" lang="ru"><span title="">Последний блок запускает сервер через порт «3000» и печатает комментарий журнала в консоль.</span> <span title="">Когда сервер работает, вы можете перейти к localhost: 3000 в вашем браузере, чтобы увидеть возвращённый пример ответа.</span></span></p>

<h3 id="Импорт_и_создание_модулей"><span class="tlid-translation translation" lang="ru"><span title="">Импорт и создание модулей</span></span></h3>

<p><span class="tlid-translation translation" lang="ru"><span title="">Модуль - это библиотека / файл JavaScript, который вы можете импортировать в другой код с помощью функции require () Node.</span> <span title="">Express сам по себе является модулем, как и промежуточное программное обеспечение и библиотеки баз данных, которые мы используем в наших приложениях Express.</span><br>
 <br>
 <span title="">Приведённый ниже код показывает, как мы импортируем модуль по имени, используя в качестве примера платформу Express.</span> <span title="">Сначала мы вызываем функцию require (), определяя имя модуля в виде строки («express») и вызывая возвращённый объект для создания приложения Express.</span> <span title="">Затем мы можем получить доступ к свойствам и функциям объекта приложения.</span></span></p>

<pre class="brush: js notranslate">var express = require('express');
var app = express();
</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Вы также можете создавать свои собственные модули, которые можно импортировать таким же образом.</span></span></p>

<div class="note">
<p><span class="tlid-translation translation" lang="ru"><span title="">Совет: вы захотите создать свои собственные модули, потому что это позволяет вам организовать ваш код в управляемые части - монолитное однофайловое приложение трудно понять и поддерживать.</span> <span title="">Использование модулей также помогает вам управлять пространством имён, поскольку при использовании модуля импортируются только те переменные, которые вы явно экспортировали.</span></span></p>
</div>

<p><span class="tlid-translation translation" lang="ru"><span title="">Чтобы сделать объекты доступными вне модуля, вам просто нужно назначить их объекту экспорта.</span> <span title="">Например, модуль square.js ниже представляет собой файл, который экспортирует методы area () и perimeter ():</span></span></p>

<pre class="brush: js notranslate">exports.area = function(width) { return width * width; };
exports.perimeter = function(width) { return 4 * width; };
</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Мы можем импортировать этот модуль, используя require (), а затем вызвать экспортированные методы, как показано:</span></span></p>

<pre class="brush: js notranslate">var square = require('./square'); // Here we require() the name of the file without the (optional) .js file extension
console.log('The area of a square with a width of 4 is ' + square.area(4));</pre>

<div class="note">
<p><span class="tlid-translation translation" lang="ru"><span title="">Примечание. Вы также можете указать абсолютный путь к модулю (или имя, как мы делали изначально).</span></span></p>
</div>

<p><span class="tlid-translation translation" lang="ru"><span title="">Если вы хотите экспортировать полный объект в одном назначении, а не создавать его по одному свойству за раз, назначьте его для module.exports, как показано ниже (вы также можете сделать это, чтобы сделать корень объекта экспорта конструктором или другой функцией)</span> <span title="">:</span></span></p>

<pre class="brush: js notranslate">module.exports = {
  area: function(width) {
    return width * width;
  },

  perimeter: function(width) {
    return 4 * width;
  }
};
</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Для получения дополнительной информации о модулях см.</span></span> <a href="https://nodejs.org/api/modules.html#modules_modules">Modules</a> (Node API docs).</p>

<h3 id="Использование_асинхронных_API"><span class="tlid-translation translation" lang="ru"><span title="">Использование асинхронных API</span></span></h3>

<p><span class="tlid-translation translation" lang="ru"><span title="">Код JavaScript часто использует асинхронные, а не синхронные API для операций, выполнение которых может занять некоторое время.</span> <span title="">Синхронный API - это тот, в котором каждая операция должна завершиться до начала следующей операции.</span> <span title="">Например, следующие функции журнала являются синхронными и выводят текст на консоль по порядку (первый, второй).</span></span></p>

<pre class="brush: js notranslate">console.log('First');
console.log('Second');
</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">В отличие от этого, асинхронный API - это тот, в котором API начнёт операцию и сразу же вернётся (до завершения операции).</span> <span title="">После завершения операции API будет использовать некоторый механизм для выполнения дополнительных операций.</span> <span title="">Например, приведённый ниже код выведет «Second, First», потому что хотя метод setTimeout () вызывается первым и возвращается немедленно, операция не завершается в течение нескольких секунд.</span></span></p>

<pre class="brush: js notranslate">setTimeout(function() {
   console.log('First');
   }, 3000);
console.log('Second');
</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Использование неблокирующих асинхронных API-интерфейсов ещё более важно в Node, чем в браузере, поскольку Node - это однопоточная среда выполнения, управляемая событиями.</span> <span title="">«Однопоточный» означает, что все запросы к серверу выполняются в одном потоке (а не порождаются в отдельных процессах).</span> <span title="">Эта модель чрезвычайно эффективна с точки зрения скорости и ресурсов сервера, но это означает, что если любая из ваших функций вызывает синхронные методы, выполнение которых занимает много времени, они будут блокировать не только текущий запрос, но и любой другой запрос, обрабатываемый</span> <span title="">ваше веб-приложение.</span><br>
 <br>
 <span title="">Есть несколько способов, которыми асинхронный API уведомляет ваше приложение о том, что оно завершено.</span> <span title="">Наиболее распространённый способ - зарегистрировать колбэк-функцию при вызове асинхронного API, который будет вызываться после завершения операции.</span> <span title="">Это подход, использованный выше.</span></span></p>

<div class="note">
<p><span class="tlid-translation translation" lang="ru"><span title="">Совет: Использование колбэков может быть довольно «грязным», если у вас есть последовательность зависимых асинхронных операций, которые должны выполняться по порядку, потому что это приводит к нескольким уровням вложенных колбэков.</span> <span title="">Эта проблема широко известна как «ад колбэков».</span> <span title="">Эту проблему можно решить с помощью хороших методов кодирования (см. Http://callbackhell.com/), использования такого модуля, как async, или даже перехода к функциям ES6, таким как Promises.</span></span></p>
</div>

<div class="note">
<p><span class="tlid-translation translation" lang="ru"><span title="">Примечание. Общим соглашением для Node и Express является использование колбэков с ошибками.</span> <span title="">В этом соглашении первое значение в ваших колбэк-функциях является значением ошибки, в то время как последующие аргументы содержат данные об успехе.</span> <span title="">В этом блоге есть хорошее объяснение того, почему этот подход полезен: путь Node.js - понимание колбэков с ошибками (fredkschott.com).</span></span></p>
</div>

<h3 id="Создание_обработчиков_маршрута"><span class="tlid-translation translation" lang="ru"><span title="">Создание обработчиков маршрута</span></span></h3>

<p><span class="tlid-translation translation" lang="ru"><span title="">В нашем примере Hello World Express (см. Выше) мы определили функцию обработчика маршрута (колбэка) для HTTP-запросов GET к корню сайта ('/').</span></span></p>

<pre class="brush: js notranslate">app.<strong>get</strong>('/', function(req, res) {
  res.send('Hello World!');
});
</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Колбэк-функция принимает запрос и объект ответа в качестве аргументов.</span> <span title="">В этом случае метод просто вызывает send () в ответе, чтобы вернуть строку «Hello World!»</span> <span title="">Существует ряд других методов ответа для завершения цикла запрос / ответ, например, вы можете вызвать res.json () для отправки ответа JSON или res.sendFile () для отправки файла.</span></span></p>

<div class="note">
<p><span class="tlid-translation translation" lang="ru"><span title="">Совет по JavaScript: вы можете использовать любые имена аргументов, которые вам нравятся, в колбэк-функциях;</span> <span title="">при вызове колбэка первый аргумент всегда будет запросом, а второй всегда будет ответом.</span> <span title="">Имеет смысл назвать их так, чтобы вы могли идентифицировать объект, с которым работаете, в теле колбэка.</span></span></p>
</div>

<p><span class="tlid-translation translation" lang="ru"><span title="">Объект приложения Express также предоставляет методы для определения обработчиков маршрутов для всех других HTTP-глаголов, которые в основном используются одинаково: post (), put (), delete (), options (), trace (), copy (</span> <span title="">), lock (), mkcol (), move (), purge (), propfind (), proppatch (), unlock (), report (), mkactivity (), checkout (), merge (</span> <span title="">), m-search (), notify (), subscribe (), unsubscribe (), patch (), search () и connect ().</span></span></p>

<p><span class="tlid-translation translation" lang="ru"><span title="">Существует специальный метод маршрутизации app.all (), который будет вызываться в ответ на любой метод HTTP.</span> <span title="">Это используется для загрузки функций промежуточного программного обеспечения по определённому пути для всех методов запроса.</span> <span title="">В следующем примере (из документации Express) показан обработчик, который будет выполняться для запросов к / secret независимо от используемого глагола HTTP (при условии, что он поддерживается модулем http).</span></span></p>

<pre class="brush: js notranslate">app.all('/secret', function(req, res, next) {
  console.log('Accessing the secret section ...');
  next(); // pass control to the next handler
});</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Маршруты позволяют сопоставлять определённые шаблоны символов в URL-адресе, извлекать некоторые значения из URL-адреса и передавать их в качестве параметров обработчику маршрута (в качестве атрибутов объекта запроса, передаваемого в качестве параметра).</span><br>
 <br>
 <span title="">Часто полезно группировать обработчики маршрутов для определённой части сайта и получать к ним доступ с помощью общего префикса маршрута (например, сайт с вики может иметь все связанные с вики маршруты в одном файле и иметь к ним доступ с префиксом маршрута</span> <span title="">из / вики /).</span> <span title="">В Express это достигается с помощью объекта express.Router.</span> <span title="">Например, мы можем создать наш вики-маршрут в модуле с именем wiki.js, а затем экспортировать объект Router, как показано ниже:</span></span></p>

<pre class="brush: js notranslate">// wiki.js - Wiki route module

var express = require('express');
var router = express.Router();

// Home page route
router.get('/', function(req, res) {
  res.send('Wiki home page');
});

// About page route
router.get('/about', function(req, res) {
  res.send('About this wiki');
});

module.exports = router;
</pre>

<div class="note">
<p><span class="tlid-translation translation" lang="ru"><span title="">Примечание. Добавление маршрутов к объекту Router аналогично добавлению маршрутов к объекту приложения (как показано ранее).</span></span></p>
</div>

<p><span class="tlid-translation translation" lang="ru"><span title="">Чтобы использовать маршрутизатор в нашем главном файле приложения, нам потребуется () модуль route (wiki.js), а затем вызовите use () в приложении Express, чтобы добавить маршрутизатор в путь обработки промежуточного программного обеспечения.</span> <span title="">Эти два маршрута будут доступны из / wiki / и / wiki / about /.</span></span></p>

<pre class="brush: js notranslate">var wiki = require('./wiki.js');
// ...
app.use('/wiki', wiki);</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Мы покажем вам намного больше о работе с маршрутами, и в частности об использовании маршрутизатора, позже в связанном разделе</span></span> <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/routes"> Routes and controllers .</a></p>

<h3 id="Использование_промежуточного_программного_обеспечения"><span class="tlid-translation translation" lang="ru"><span title="">Использование промежуточного программного обеспечения</span></span></h3>

<p><span class="tlid-translation translation" lang="ru"><span title="">Промежуточное программное обеспечение широко используется в приложениях Express для задач от обслуживания статических файлов до обработки ошибок и сжатия HTTP-ответов.</span> <span title="">Принимая во внимание, что функции маршрута заканчивают цикл запроса-ответа HTTP, возвращая некоторый ответ клиенту HTTP, функции промежуточного программного обеспечения обычно выполняют некоторую операцию над запросом или ответом и затем вызывают следующую функцию в «стеке», которая может быть большим количеством промежуточного программного обеспечения или маршрута</span> <span title="">обработчик</span><span title="">.</span> <span title="">Порядок вызова промежуточного программного обеспечения зависит от разработчика приложения.</span></span></p>

<div class="note">
<p><span class="tlid-translation translation" lang="ru"><span title="">Примечание. Промежуточное программное обеспечение может выполнять любую операцию, выполнять любой код, вносить изменения в объект запроса и ответа, а также может завершать цикл запрос-ответ.</span> <span title="">Если он не завершает цикл, он должен вызвать next (), чтобы передать управление следующей функции промежуточного программного обеспечения (или запрос останется зависшим).</span></span></p>
</div>

<p><span class="tlid-translation translation" lang="ru"><span title="">Большинство приложений используют стороннее промежуточное программное обеспечение для упрощения общих задач веб-разработки, таких как работа с файлами cookie, сессиями, аутентификацией пользователя, доступом к данным запросов POST и JSON, ведение журнала и т. д. Список пакетов промежуточного программного обеспечения, поддерживаемых командой Express, можно найти.</span> <span title="">(который также включает в себя другие популярные сторонние пакеты).</span> <span title="">Другие экспресс-пакеты доступны в диспетчере пакетов NPM.</span><br>
 <br>
 <span title="">Для использования стороннего промежуточного программного обеспечения сначала необходимо установить его в своё приложение с помощью NPM.</span> <span title="">Например, чтобы установить промежуточное программное обеспечение средства регистрации HTTP-запросов morgan, вы должны сделать следующее:</span></span></p>

<pre class="brush: bash notranslate"><code>$ npm install morgan
</code></pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Затем вы можете вызвать use () для объекта приложения Express, чтобы добавить промежуточное программное обеспечение в стек:</span></span></p>

<pre class="brush: js notranslate">var express = require('express');
<strong>var logger = require('morgan');</strong>
var app = express();
<strong>app.use(logger('dev'));</strong>
...</pre>

<div class="note">
<p><span class="tlid-translation translation" lang="ru"><span title="">Примечание. Промежуточное программное обеспечение и функции маршрутизации вызываются в том порядке, в котором они были объявлены.</span> <span title="">Для некоторого промежуточного программного обеспечения важен порядок (например, если промежуточное программное обеспечение сеанса зависит от промежуточного программного обеспечения cookie, то сначала должен быть добавлен обработчик cookie).</span> <span title="">Почти всегда случается так, что промежуточное ПО вызывается перед настройкой маршрутов, иначе ваши обработчики маршрутов не будут иметь доступа к функциям, добавленным вашим промежуточным ПО.</span></span></p>
</div>

<p><span class="tlid-translation translation" lang="ru"><span title="">Вы можете написать свои собственные функции промежуточного программного обеспечения, и вам, вероятно, придётся это сделать (хотя бы для создания кода обработки ошибок).</span> <span title="">Единственное различие между функцией промежуточного программного обеспечения и обратным вызовом обработчика маршрута состоит в том, что функции промежуточного программного обеспечения имеют третий аргумент, следующий: какие функции промежуточного программного обеспечения должны вызываться, если они не завершают цикл запроса (когда вызывается функция промежуточного программного обеспечения, она содержит следующую функцию).</span> <span title="">это надо называть).</span></span></p>

<p><span class="tlid-translation translation" lang="ru"><span title="">Вы можете добавить функцию промежуточного программного обеспечения в цепочку обработки с помощью app.use () или app.add (), в зависимости от того, хотите ли вы применить промежуточное программное обеспечение ко всем ответам или к ответам с определённым глаголом HTTP (GET, POST и т. д.).</span> <span title="">)</span><span title="">.</span> <span title="">Маршруты задаются одинаково в обоих случаях, хотя маршрут необязателен при вызове app.use ().</span><br>
 <br>
 <span title="">В приведённом ниже примере показано, как можно добавить функцию промежуточного программного обеспечения, используя оба метода, а также с / без маршрута.</span></span></p>

<pre class="brush: js notranslate">var express = require('express');
var app = express();

// An example middleware function
var a_middleware_function = function(req, res, <em>next</em>) {
  // ... perform some operations
  next(); // Call next() so Express will call the next middleware function in the chain.
}

// Function added with use() for all routes and verbs
app.use(a_middleware_function);

// Function added with use() for a specific route
app.use('/someroute', a_middleware_function);

// A middleware function added for a specific HTTP verb and route
app.get('/', a_middleware_function);

app.listen(3000);</pre>

<div class="note">
<p><span class="tlid-translation translation" lang="ru"><span title="">Совет по JavaScript: выше мы объявляем функцию промежуточного программного обеспечения отдельно, а затем устанавливаем её в качестве колбэка.</span> <span title="">В нашей предыдущей функции обработчика маршрута мы объявили колбэк-функцию, когда она использовалась.</span> <span title="">В JavaScript любой подход является допустимым.</span></span></p>
</div>

<p><span class="tlid-translation translation" lang="ru"><span title="">Документация по Express содержит намного больше отличной информации по использованию и написанию промежуточного программного обеспечения Express.</span></span></p>

<h3 id="Обслуживание_статических_файлов"><span class="tlid-translation translation" lang="ru"><span title="">Обслуживание статических файлов</span></span></h3>

<p><span class="tlid-translation translation" lang="ru"><span title="">Вы можете использовать промежуточное программное обеспечение express.static для обслуживания статических файлов, включая ваши изображения, CSS и JavaScript (static () - единственная функция промежуточного программного обеспечения, которая фактически является частью Express).</span> <span title="">Например, вы должны использовать строку ниже для обслуживания изображений, файлов CSS и файлов JavaScript из каталога с именем public на том же уровне, где вы вызываете узел:</span></span></p>

<pre class="brush: js notranslate">app.use(express.static('public'));
</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Любые файлы в публичном каталоге обслуживаются путём добавления их имени файла (относительно базового «публичного» каталога) к базовому URL.</span> <span title="">Так, например:</span></span></p>

<pre class="notranslate"><code>http://localhost:3000/images/dog.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost:3000/about.html
</code></pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Вы можете вызывать static () несколько раз для обслуживания нескольких каталогов.</span> <span title="">Если файл не может быть найден одной функцией промежуточного программного обеспечения, он будет просто передан последующему промежуточному программному обеспечению (порядок вызова промежуточного программного обеспечения основан на вашем порядке объявления).</span></span></p>

<pre class="brush: js notranslate">app.use(express.static('public'));
app.use(express.static('media'));
</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Вы также можете создать виртуальный префикс для ваших статических URL-адресов, вместо добавления файлов к базовому URL-адресу.</span> <span title="">Например, здесь мы указываем путь монтирования, чтобы файлы загружались с префиксом "/ media":</span></span></p>

<pre class="brush: js notranslate">app.use('/media', express.static('public'));
</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Теперь вы можете загружать файлы, находящиеся в публичном каталоге, из префикса / media path.</span></span></p>

<pre class="notranslate"><code>http://localhost:3000/media/images/dog.jpg
http://localhost:3000/media/video/cat.mp4
http://localhost:3000/media/cry.mp3</code>
</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Для получения дополнительной информации см.</span></span> <a href="Serving static files in Express">Serving static files in Express</a>.</p>

<h3 id="Обработка_ошибок"><span class="tlid-translation translation" lang="ru"><span title="">Обработка ошибок</span></span></h3>

<p><span class="tlid-translation translation" lang="ru"><span title="">Ошибки обрабатываются одной или несколькими специальными функциями промежуточного программного обеспечения, которые имеют четыре аргумента вместо обычных трёх: (err, req, res, next).</span> <span title="">Например:</span></span></p>

<pre class="brush: js notranslate">app.use(function(err, req, res, next) {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});
</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Они могут возвращать любой требуемый контент, но должны вызываться после всех других app.use () и маршрутизировать вызовы, чтобы они были последним промежуточным ПО в процессе обработки запросов!</span><br>
 <br>
 <span title="">Express поставляется со встроенным обработчиком ошибок, который заботится обо всех оставшихся ошибках, которые могут возникнуть в приложении.</span> <span title="">Эта промежуточная функция обработки ошибок по умолчанию добавляется в конец стека функций промежуточного программного обеспечения.</span> <span title="">Если вы передаёте ошибку в next () и не обрабатываете её в обработчике ошибок, она будет обработана встроенным обработчиком ошибок;</span> <span title="">ошибка будет записана клиенту с трассировкой стека.</span></span></p>

<div class="note">
<p><span class="tlid-translation translation" lang="ru"><span title="">Примечание. Трассировка стека не включена в производственную среду.</span> <span title="">Чтобы запустить его в производственном режиме, необходимо установить переменную среды NODE_ENV в «производство».</span></span></p>
</div>

<div class="note">
<p><span class="tlid-translation translation" lang="ru"><span title="">Примечание. HTTP404 и другие коды состояния «ошибка» не считаются ошибками.</span> <span title="">Если вы хотите справиться с этим, вы можете добавить функцию промежуточного программного обеспечения для этого.</span> <span title="">Для получения дополнительной информации см. FAQ.</span></span></p>
</div>

<p><span class="tlid-translation translation" lang="ru"><span title="">Для получения дополнительной информации см.</span></span> <a href="http://expressjs.com/en/guide/error-handling.html">Error handling</a> (Express docs).</p>

<h3 id="Использование_баз_данных"><span class="tlid-translation translation" lang="ru"><span title="">Использование баз данных</span></span></h3>

<p><span class="tlid-translation translation" lang="ru"><span title="">Приложения Express могут использовать любой механизм базы данных, поддерживаемый Node (сам по себе Express не определяет каких-либо дополнительных действий / требований для управления базой данных).</span> <span title="">Есть много вариантов, включая PostgreSQL, MySQL, Redis, SQLite, MongoDB и т. Д.</span><br>
 <br>
 <span title="">Чтобы использовать их, вы должны сначала установить драйвер базы данных, используя NPM.</span> <span title="">Например, чтобы установить драйвер для популярной NoSQL MongoDB, вы должны использовать команду:</span></span></p>

<pre class="brush: bash notranslate"><code>$ npm install mongodb
</code></pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Сама база данных может быть установлена локально или на облачном сервере.</span> <span title="">В вашем экспресс-коде вам требуется драйвер, подключиться к базе данных, а затем выполнить операции создания, чтения, обновления и удаления (CRUD).</span> <span title="">Пример ниже (из документации Express) показывает, как вы можете найти записи «млекопитающих», используя MongoDB.</span></span></p>

<pre class="brush: js notranslate">var MongoClient = require('mongodb').MongoClient;

MongoClient.connect('mongodb://localhost:27017/animals', function(err, db) {
  if (err) throw err;

  db.collection('mammals').find().toArray(function (err, result) {
    if (err) throw err;

    console.log(result);
  });
});</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Другим популярным подходом является косвенный доступ к вашей базе данных с помощью Object Relational Mapper («ORM»).</span> <span title="">При таком подходе вы определяете свои данные как «объекты» или «модели», и ORM отображает их в базовый формат базы данных.</span> <span title="">Этот подход имеет то преимущество, что как разработчик вы можете продолжать думать с точки зрения объектов JavaScript, а не семантики базы данных, и что есть очевидное место для выполнения проверки и проверки входящих данных.</span> <span title="">Подробнее о базах данных мы поговорим в следующей статье.</span></span></p>

<p><span class="tlid-translation translation" lang="ru"><span title="">Для получения дополнительной информации см.</span></span> <a href="https://expressjs.com/en/guide/database-integration.html">Database integration</a> (Express docs).</p>

<h3 id="Рендеринг_данных_просмотров"><span class="tlid-translation translation" lang="ru"><span title="">Рендеринг данных (просмотров)</span></span></h3>

<p><span class="tlid-translation translation" lang="ru"><span title="">Механизмы шаблонов (в Express называемые «механизмами просмотра») позволяют указывать структуру выходного документа в шаблоне, используя заполнители для данных, которые будут заполняться при создании страницы.</span> <span title="">Шаблоны часто используются для создания HTML, но могут также создавать другие типы документов.</span> <span title="">В Express есть поддержка ряда шаблонных движков, и здесь есть полезное сравнение более популярных движков: Сравнение шаблонизаторов JavaScript: Jade, Mustache, Dust и More.</span><br>
 <br>
 <span title="">В своём коде настроек приложения вы задаёте механизм шаблонов для использования и место, где Express должен искать шаблоны, используя настройки «views» и «engine», как показано ниже (вам также нужно будет установить пакет, содержащий вашу библиотеку шаблонов).</span> <span title="">!</span><span title="">)</span></span></p>

<pre class="brush: js notranslate">var express = require('express');
var app = express();

// Set directory to contain the templates ('views')
app.set('views', path.join(__dirname, 'views'));

// Set view engine to use, in this case 'some_template_engine_name'
app.set('view engine', 'some_template_engine_name');
</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Внешний вид шаблона будет зависеть от того, какой движок вы используете.</span> <span title="">Предполагая, что у вас есть файл шаблона с именем «index. &lt;Template_extension&gt;», который содержит заполнители для переменных данных с именами «title» и «message», вы должны вызвать Response.render () в функции обработчика маршрута для создания и отправки ответа HTML.</span> <span title="">:</span></span></p>

<pre class="brush: js notranslate">app.get('/', function(req, res) {
  res.render('index', { title: 'About dogs', message: 'Dogs rock!' });
});</pre>

<p><span class="tlid-translation translation" lang="ru"><span title="">Для получения дополнительной информации см.</span></span> <a href="http://expressjs.com/en/guide/using-template-engines.html">Using template engines with Express</a> (Express docs).</p>

<h3 id="Файловая_структура"><span class="tlid-translation translation" lang="ru"><span title="">Файловая структура</span></span></h3>

<p><span class="tlid-translation translation" lang="ru"><span title="">Express не делает никаких предположений относительно структуры или компонентов, которые вы используете.</span> <span title="">Маршруты, представления, статические файлы и другая логика конкретного приложения могут находиться в любом количестве файлов с любой структурой каталогов.</span> <span title="">Хотя вполне возможно иметь все приложения Express в одном файле, обычно имеет смысл разделить ваше приложение на файлы на основе функций (например, управление учётными записями, блоги, доски обсуждений) и проблемной области архитектуры (например, модель, представление или контроллер, если</span> <span title="">вы случайно используете</span></span> <a href="/en-US/docs/Web/Apps/Fundamentals/Modern_web_app_architecture/MVC_architecture">MVC architecture</a>).</p>

<p><span class="tlid-translation translation" lang="ru"><span title="">В более поздней теме мы будем использовать Express Application Generator, который создаёт модульный каркас приложения, который мы можем легко расширить для создания веб-приложений.</span></span></p>

<ul>
</ul>

<h2 id="Резюме">Резюме</h2>

<p><span class="tlid-translation translation" lang="ru"><span title="">Поздравляем, вы завершили первый шаг в своём путешествии Express / Node!</span> <span title="">Теперь вы должны понимать основные преимущества Express и Node, а также примерно то, как могут выглядеть основные части приложения Express (маршруты, промежуточное ПО, обработка ошибок и код шаблона).</span> <span title="">Вы также должны понимать, что с Express, который является непонятным фреймворком, то, как вы собираете эти части вместе, и библиотеки, которые вы используете, в значительной степени зависит от вас!</span><br>
 <br>
 <span title="">Конечно, Express - это очень лёгкая платформа для веб-приложений, поэтому большая часть её преимуществ и возможностей обеспечивается сторонними библиотеками и функциями.</span> <span title="">Мы рассмотрим это более подробно в следующих статьях.</span> <span title="">В нашей следующей статье мы рассмотрим настройку среды разработки Node, чтобы вы могли увидеть некоторый код Express в действии.</span></span></p>

<h2 id="Смотрите_также">Смотрите также</h2>

<ul>
 <li><a href="https://nodejs.org/api/modules.html#modules_modules">Modules</a> (Node API docs)</li>
 <li><a href="https://expressjs.com/">Express</a> (home page)</li>
 <li><a href="http://expressjs.com/en/starter/basic-routing.html">Basic routing</a> (Express docs)</li>
 <li><a href="http://expressjs.com/en/guide/routing.html">Routing guide</a> (Express docs)</li>
 <li><a href="http://expressjs.com/en/guide/using-template-engines.html">Using template engines with Express</a> (Express docs)</li>
 <li><a href="https://expressjs.com/en/guide/using-middleware.html">Using middleware</a> (Express docs)</li>
 <li><a href="http://expressjs.com/en/guide/writing-middleware.html">Writing middleware for use in Express apps</a> (Express docs)</li>
 <li><a href="https://expressjs.com/en/guide/database-integration.html">Database integration</a> (Express docs)</li>
 <li><a href="Serving static files in Express">Serving static files in Express</a> (Express docs)</li>
 <li><a href="http://expressjs.com/en/guide/error-handling.html">Error handling</a> (Express docs)</li>
</ul>

<div>{{NextMenu("Learn/Server-side/Express_Nodejs/development_environment", "Learn/Server-side/Express_Nodejs")}}</div>

<div id="gtx-anchor" style="position: absolute; left: 20px; top: 6224px; width: 616.578px; height: 17px;"></div>

<div class="jfk-bubble gtx-bubble">
<div class="jfk-bubble-content-id" id="bubble-22">
<div id="gtx-host" style="max-width: 400px;"></div>
</div>

<div class="jfk-bubble-closebtn-id jfk-bubble-closebtn"></div>

<div class="jfk-bubble-arrow-id jfk-bubble-arrow jfk-bubble-arrowup" style="left: 288.5px;">
<div class="jfk-bubble-arrowimplbefore"></div>

<div class="jfk-bubble-arrowimplafter"></div>
</div>
</div>