/
64mb
/
node-labs-ru
Обзор
Документация
Войти
/
64mb
/
node-labs-ru
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
master
shell.html
280 строк
33 KB
Georgy Malkov
init
03 ноя 2021, 12:02
03 ноя 2021, 12:02
49d714e
Код
Авторство
О чём код?
<!DOCTYPE html> <html> <!-- Mirrored from www.nodelabs.org/shell.html by HTTrack Website Copier/3.x [XR&CO'2014], Mon, 04 Sep 2017 18:01:54 GMT --> <!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=utf-8" /><!-- /Added by HTTrack --> <head> <title>Node.js Shell - Node Labs</title> <link href="css/post.css" rel="stylesheet" type="text/css"/> <link href="css/pygments.css" rel="stylesheet" type="text/css"/> <link href='http://fonts.googleapis.com/css?family=Droid+Sans:400,700|Droid+Sans+Mono' rel='stylesheet' type='text/css' /> <script src="../ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script src="../cdn.jsdelivr.net/jquery.cookie/1.3.1/jquery.cookie.js"></script> <script src="../nodelabs.herokuapp.com/socket.io/socket.io.html"></script> <script src="js/unlock.js"></script> <script type="text/javascript"> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','../www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-35011668-1', 'nodelabs.org'); ga('require', 'linkid', 'linkid.html'); ga('send', 'pageview'); </script> </head> <body> <div id="header"> <a href="index.html" title="Take me home!"><img src="css/img/logotype_dark.png" /></a> </div> <h1 id="a-nodejs-shell">Node.js Shell</h1> <p>В данной лабораторной работе мы разработаем простую оболочку (программу принимающую команды). Рассмотрим взаимодействие с файловой системой и сетью и изучим некоторые полезные функции JavaScript.</p> <ul> <li><a href="#working_with_standard_input">Работа со стандартным вводом</a></li> <li><a href="#implementing_a_print_working_directory_command">Внедрение команд вывода рабочего каталога</a></li> <li><a href="#interacting_with_the_file_system_reading_a_directory">Взаимодейтсвие с файловой системой: чтение каталога</a></li> <li><a href="#interacting_with_http_downloading_a_file">Взаимодействие с HTTP: загрузка файла</a></li> </ul> <h1 id="working_with_standard_input">Работа со стандартным вводом</h1> <p>Команды будут передаваться нашей оболочке, через стандартный ввод. По умолчанию, у Node.js поток стандартного ввода не активирован. Первым делом, мы подключим стандартный ввод и выведем то, что считаем.</p> <p>Создадим новый файл <code>shell.js</code> в новом каталоге и добавим в него следующее:</p> <div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">process</span><span class="p">.</span><span class="nx">stdin</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">input</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">input</span><span class="p">);</span> <span class="p">});</span></code></pre></div> <p>Перед тем как пойти дальше, давайте поэксперементируем с предыдущей программой. Для этого запустите файл:</p> <div class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>node shell.js</code></pre></div> <p>Введите что-нибудь и нажмите Enter. Обратите внимание, что ввод в строке буфферизирован (данные отправляются в Node.js каждый раз, когда вы нажимаете Enter). Для завершения процесса ввода нажмите <code>CTRL+C</code>.</p> <p>Вывод программы будет выглядеть примерно так:</p> <div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">foo</span> <span class="o"><</span><span class="nx">Buffer</span> <span class="mi">61</span> <span class="mi">73</span> <span class="mi">64</span> <span class="mi">0</span><span class="nx">a</span><span class="o">></span> <span class="nx">bar</span> <span class="o"><</span><span class="nx">Buffer</span> <span class="mi">62</span> <span class="mi">61</span> <span class="mi">72</span> <span class="mi">0</span><span class="nx">a</span><span class="o">></span></code></pre></div> <p>Вы можете заметить, что выводится объект типа <code>Buffer</code>. Это потому, что <code>input</code> переменная, принята в нашу функцию <code>function (input) { ... }</code>, в которой обратная связь не содержит строковое значение вашего ввода напрямую.</p> <p>Стоит отметить, что буфер существует полностью за пределами пространства памяти JavaScript (<code>Buffer</code> - объект внутри C++ Node.js). Взаимодействие с буфером будет перемещать данные между нативом (C++) и JavaScript. Для примера, вызов <code>input.toString()</code> создаст новую строку JavaScript содержащую все данные из <code>Buffer</code>. Необязательный параметр кодировки может быть указана как первый аргумент функции <code>toString</code> (для примера, <code>input.toString('utf8')</code>).</p> <p>Так как мы работаем с относительно короткими строками, то давайте попробуем опрадиться к объекту буфера <code>input.toString()</code>. Вот так выглдит ваша программа сейчас:</p> <div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">process</span><span class="p">.</span><span class="nx">stdin</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">input</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">toString</span><span class="p">());</span> <span class="p">});</span></code></pre></div> <p>Теперь запуск оболочки и ввод любого значения приведет к ожидаемому результату, с новым символом строки на конце.</p> <p>Следующим шагом будет сокращение и считывание введеной строки. Команды в нашей оболочке примут такую форму:</p> <div class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">command</span> <span class="o">[</span>args...<span class="o">]</span></code></pre></div> <p>Мы можем использовать удобное регулярное выражение для разделения аргументов из команды: <code>/(\w+)(.*)/</code>. Мы можем считать аргументы, разделив их по символу пробела.</p> <div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">process</span><span class="p">.</span><span class="nx">stdin</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">input</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">matches</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">toString</span><span class="p">().</span><span class="nx">match</span><span class="p">(</span><span class="sr">/(\w+)(.*)/</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">command</span> <span class="o">=</span> <span class="nx">matches</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">toLowerCase</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="nx">matches</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="nx">trim</span><span class="p">().</span><span class="nx">split</span><span class="p">(</span><span class="sr">/\s+/</span><span class="p">);</span> <span class="p">});</span></code></pre></div> <h3 id="a-side-note">Примечание</h3> <p>Результатом выполнения кода <code>'some string'.split(/\s+/)</code> будет массив <code>['some', 'string']</code>.</p> <p>Данный пример можно переписать по другому <code>'some string'.split(' ')</code>, при условии, что не учитываются другие типы непробельных символов или несколько символов пробела. Для примера:</p> <p><code>'some string'.split(' ')</code> приведет к созданию массива <code>['some', '', 'string']</code>.</p> <p>Попробуйте проверить результат вышеуказанного кода, подбирая значения <code>command</code> и <code>args</code>. Добавьте больше логики (логической проверки), чтобы сделать данный код усточивей к неверному вводу. Это первое упражнение для вас. По выполнению задания, представьте его прподавателю.</p> <h2 id="implementing_a_print_working_directory_command">Внедрение команд вывода рабочего каталога</h2> <p><code>pwd</code> является простой командой для вывода текущего рабочего каталога. Давайте реализуем его в нашей оболочке.</p> <div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">commands</span> <span class="o">=</span> <span class="p">{</span> <span class="s1">'pwd'</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">process</span><span class="p">.</span><span class="nx">cwd</span><span class="p">());</span> <span class="p">}</span> <span class="p">};</span> <span class="nx">process</span><span class="p">.</span><span class="nx">stdin</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">input</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">matches</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">toString</span><span class="p">().</span><span class="nx">match</span><span class="p">(</span><span class="sr">/(\w+)(.*)/</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">command</span> <span class="o">=</span> <span class="nx">matches</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">toLowerCase</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="nx">matches</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="nx">trim</span><span class="p">().</span><span class="nx">split</span><span class="p">(</span><span class="sr">/\s+/</span><span class="p">);</span> <span class="nx">commands</span><span class="p">[</span><span class="nx">command</span><span class="p">](</span><span class="nx">args</span><span class="p">);</span> <span class="p">});</span></code></pre></div> <p>Чтобы прояснить, что происходит выше, вот пример вывода выполнения регулярного выражения в Node.js REPL. Выполним <code>cmd_name arg1 arg2</code>.</p> <div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="o">></span> <span class="kd">var</span> <span class="nx">input</span> <span class="o">=</span> <span class="s1">'cmd_name arg1 arg2'</span> <span class="s1">'cmd_name arg1 arg2'</span> <span class="o">></span> <span class="kd">var</span> <span class="nx">matches</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/(\w+)(.*)/</span><span class="p">)</span> <span class="o">></span> <span class="nx">matches</span> <span class="p">[</span> <span class="s1">'cmd_name arg1 arg2'</span><span class="p">,</span> <span class="c1">// matches[0]</span> <span class="s1">'cmd_name'</span><span class="p">,</span> <span class="c1">// matches[1]</span> <span class="s1">' arg1 arg2'</span><span class="p">,</span> <span class="c1">// matches[2]</span> <span class="nx">index</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="c1">// matches[3]</span> <span class="nx">input</span><span class="o">:</span> <span class="s1">'cmd_name arg1 arg2'</span><span class="p">]</span> <span class="c1">// matches[4]</span></code></pre></div> <p>Мы обращаемся к элементу массива <code>matches[1]</code> потому что это первая группа регулярного выражения (группы указаны в скобках). Если вы не знакомы с регулярными выражениями, то можете почитать здесь: <a href="http://www.regular-expressions.info/">http://regular-expressions.info</a> или уточнить у преподавателя.</p> <p>Теперь попробуйте в действии свою оболочку!</p> <p>Запустите оболочку с помощью команды <code>node</code> и выполните только одну команду:</p> <div class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>node shell.js <span class="nb">pwd</span> /users/you/simple-shell/</code></pre></div> <h2 id="interacting_with_the_file_system_reading_a_directory">Взаимодейтсвие с файловой системой: чтение каталога</h2> <p>Команда <code>ls [directory]</code> выводит содержимое каталога. Если аргумент не указан, он выведет содержимое текущего рабочего каталога.</p> <p>Во-первых, мы импортируем модуль <code>fs</code> в начале файла. Модуль <code>fs</code> - это базовый модуль Node.js для работы с файловой системой.</p> <div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">fs</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'fs'</span><span class="p">);</span></code></pre></div> <p>Чтобы реализовать команду <code>ls</code>, добавьте новое свойство в наш объект с именем 'ls':</p> <div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">commands</span> <span class="o">=</span> <span class="p">{</span> <span class="s1">'pwd'</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">process</span><span class="p">.</span><span class="nx">cwd</span><span class="p">());</span> <span class="p">},</span> <span class="c1">// <----------------------- не забудьте эту запятую!</span> <span class="s1">'ls'</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">args</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Новое свойство добавлено здесь.</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">readdir</span><span class="p">(</span><span class="nx">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">||</span> <span class="nx">process</span><span class="p">.</span><span class="nx">cwd</span><span class="p">(),</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">entries</span><span class="p">)</span> <span class="p">{</span> <span class="nx">entries</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">e</span><span class="p">);</span> <span class="p">});</span> <span class="p">});</span> <span class="p">}</span> <span class="p">};</span></code></pre></div> <p>Давайте рассмотрим конструкцию <code>args[0] || process.cwd()</code>:</p> <p>В отличие от многих других язвыков, JavaScript'у все-равно, если вы попытаетесь обратиться к индексу за пределами массива. Если элемента не существует, то будет возвращен <code>undefined</code>. Поскольку <code>undefined</code> считается пустышкой, используя <code>x || y</code> синтасис проверит существование <code>x</code> и если это ложно (не существует), то будет проверять <code>y</code>. Это простой шаблон для установки значения по умолчанию.</p> <p>Для доступа к файловой системе существует множество других команд. Попробуйте <a href="http://nodejs.org/api/fs.html"> ознакомиться с документацией</a> и испробовать другие команды, которые заинтересовали вас.</p> <p>Вот так выглядит ваша итоговая программа:</p> <div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">fs</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'fs'</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">commands</span> <span class="o">=</span> <span class="p">{</span> <span class="s1">'pwd'</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">process</span><span class="p">.</span><span class="nx">cwd</span><span class="p">());</span> <span class="p">},</span> <span class="s1">'ls'</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">args</span><span class="p">)</span> <span class="p">{</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">readdir</span><span class="p">(</span><span class="nx">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">||</span> <span class="nx">process</span><span class="p">.</span><span class="nx">cwd</span><span class="p">(),</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">entries</span><span class="p">)</span> <span class="p">{</span> <span class="nx">entries</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">e</span><span class="p">);</span> <span class="p">});</span> <span class="p">});</span> <span class="p">}</span> <span class="p">};</span> <span class="nx">process</span><span class="p">.</span><span class="nx">stdin</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">input</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">matches</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">toString</span><span class="p">().</span><span class="nx">match</span><span class="p">(</span><span class="sr">/(\w+)(.*)/</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">command</span> <span class="o">=</span> <span class="nx">matches</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">toLowerCase</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="nx">matches</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="nx">trim</span><span class="p">().</span><span class="nx">split</span><span class="p">(</span><span class="sr">/\s+/</span><span class="p">);</span> <span class="nx">commands</span><span class="p">[</span><span class="nx">command</span><span class="p">](</span><span class="nx">args</span><span class="p">);</span> <span class="p">});</span></code></pre></div> <p>Объект команд может выглядить слегка страшно, когда мы всталяем столько скобок. Вместо этого мы можем определить командный объект так:</p> <div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">commands</span> <span class="o">=</span> <span class="p">{};</span> <span class="nx">commands</span><span class="p">[</span><span class="s1">'pwd'</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">process</span><span class="p">.</span><span class="nx">cwd</span><span class="p">());</span> <span class="p">};</span> <span class="nx">commands</span><span class="p">[</span><span class="s1">'ls'</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">args</span><span class="p">)</span> <span class="p">{</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">readdir</span><span class="p">(</span><span class="nx">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">||</span> <span class="nx">process</span><span class="p">.</span><span class="nx">cwd</span><span class="p">(),</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">entries</span><span class="p">)</span> <span class="p">{</span> <span class="nx">entries</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">e</span><span class="p">);</span> <span class="p">});</span> <span class="p">});</span> <span class="p">};</span></code></pre></div> <p>В этом примере мы определяем контейнерный объект <code>commands</code> и присваиваем анонимные функции свойтвами этого объекта. Основное отличие от предыдущих способов заключается в том, что определения функций не являются частью инициализатора объекта (не задаются при создании самого объекта). Эти два подхода работают одинаково.</p> <h2 id="interacting_with_http_downloading_a_file">Взаимодействие с HTTP: загрузка файла</h2> <p>Аналогично, модулю <code>fs</code>, ядро Node.js содержит модуль <code>http</code> который может использоваться в качестве HTTP-клиента или сервера. В следующей лабораторной работе вы попробуете создать HTTP-сервер, но сейчас, мы сфокусируемся на реализации простой команды <code>wget</code> для загрузки файлов.</p> <p>Импортируйте модуль <code>http</code> выше, рядом с модулем <code>fs</code>:</p> <div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">http</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'http'</span><span class="p">);</span></code></pre></div> <p>Теперь мы воспользуемся <code>http.get(url, callback)</code> для создания HTTP GET запроса и загрузки результата в файловую систему.</p> <div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">commands</span> <span class="o">=</span> <span class="p">{</span> <span class="s1">'pwd'</span><span class="o">:</span> <span class="p">...</span> <span class="p">,</span> <span class="c1">// опущено для краткости</span> <span class="s1">'ls'</span><span class="o">:</span> <span class="p">...</span> <span class="p">,</span> <span class="c1">// опущено для краткости</span> <span class="s1">'wget'</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">args</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">url</span> <span class="o">=</span> <span class="nx">args</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span> <span class="kd">var</span> <span class="nx">file</span> <span class="o">=</span> <span class="nx">args</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">||</span> <span class="s1">'download'</span><span class="p">;</span> <span class="nx">http</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">res</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">writeStream</span> <span class="o">=</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">createWriteStream</span><span class="p">(</span><span class="nx">file</span><span class="p">);</span> <span class="nx">res</span><span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">writeStream</span><span class="p">);</span> <span class="nx">res</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'end'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">url</span> <span class="o">+</span> <span class="s1">' downloaded to file \''</span> <span class="o">+</span> <span class="nx">file</span> <span class="o">+</span> <span class="s1">'\''</span><span class="p">);</span> <span class="p">});</span> <span class="p">});</span> <span class="p">}</span> <span class="p">};</span></code></pre></div> <p>Теперь, чтобы проверить работоспособность, попробуем запустить следующее: (очень важно не забывать <code>http://</code>)</p> <p><code> node shell.js wget http://google.com </code></p> <p>Вышеупомянутая команда загрузит содержимое домашней страницы Google.</p> <p>Давайте поговорим о том, что же происходит во время выполнения метода <code>http.get</code>.</p> <p>Во-первых, создается <a href="http://nodejs.org/api/stream.html#stream_class_stream_writable">записываемый поток</a> для нашей файловой системы, используя <a href="http://nodejs.org/api/fs.html#fs_fs_createwritestream_path_options">fs.createWriteStream</a>, с параметром <code>file</code> (второй параметр не обязателен и использует <code>'download'</code> по умолчанию). Данный код создаст или перезапишет файл.</p> <p>Следующее конструкция - <code>res.pipe(writeStream);</code> содержит <code>res</code> (response) объект, который не является полным HTTP-ответом. Поскольку ответ от сервера может быть большим по объему, то Node.js отдает базовый ответ, после этого связь уже будет установлена. На данный момент у нас уже будет доступ к полному набору HTTP-заголовков и стуатусу ответа от сервера, но мы пока еще не имеем доступа непосредственно к данным из ответа.</p> <p>Данные отклика передаются, как и стандартный поток ввода, который мы открыли для чтения команд с терминала. Объект <code>res</code> инициирует события <code>res.on('data')</code> и <code>res.on('end')</code>,которые могут быть напрямую переданы в наш записываемый поток. После этого начнется сохранение данных в файловой системе.</p> <p>Если вы запутались, то рассмотрите <a href="http://nodejs.org/api/http.html">руководство по HTTP-молулю</a>.</p> <div id="next"> <div class="continue"> <a href="http.html"> <!-- Please don't just skip through these, actually do the labs! --> Так держать! Переходим к следующей лабораторной работе. <span>Cоздание HTTP-сервера</span> </a> </div> </div> <div id="footer"> <p>Labs created by <a href="https://twitter.com/joeandaverde">@joeandaverde</a></p> <p>Учебный материал переведен <a href="https://t.me/Rat_Z">@Rat_Z</a> и <a href="https://t.me/Alex_Ebenrode">@Alex_Ebenrode</a></p> </div> </body> <!-- Mirrored from www.nodelabs.org/shell.html by HTTrack Website Copier/3.x [XR&CO'2014], Mon, 04 Sep 2017 18:01:55 GMT --> </html>