1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/wizardforcel-eloquent-js-3e-zh

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
20.md 46 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 29.11.2024 02:25 369bafd

Двадцать. Node.js

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

Эти главы не являются исчерпывающим введением в платформу, но они дадут вам представление о том, как работает Node.js и как его можно использовать для создания полезных программ.

Для запуска кода из этой главы вам потребуется установить Node.js версии 10 или выше. Для этого перейдите на сайт nodejs.org и следуйте инструкциям по установке для вашей операционной системы. Там же вы найдёте дополнительную документацию по Node.js.

История

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

В таких программах асинхронное программирование часто оказывается полезным. Оно позволяет программе одновременно отправлять и получать данные от нескольких устройств без необходимости сложного управления потоками и синхронизации.

Node изначально был разработан для упрощения асинхронного программирования. JavaScript хорошо подходит для систем, подобных Node. Это один из немногих языков программирования, который не имеет встроенных механизмов ввода и вывода. Поэтому JavaScript может легко адаптироваться к необычным методам ввода и вывода Node, не создавая двух несовместимых интерфейсов. Когда Node разрабатывался в 2009 году, программирование на основе обратных вызовов уже было распространено в браузерах, поэтому сообщество JavaScript было знакомо с асинхронным стилем программирования.

Команды Node

После установки Node.js на вашем компьютере, он предоставляет программу с именем node, которая используется для выполнения файлов JavaScript. Предположим, у вас есть файл hello.js, содержащий следующий код:

let message = "Hello world";
console.log(message);

Вы можете выполнить программу следующим образом:

$ node hello.js
Hello world

Метод console.log в Node похож на тот, что используется в браузере, но вместо отображения текста в консоли JavaScript браузера он выводит текст в стандартный поток вывода при выполнении из командной строки. При запуске node без параметров, node предложит вам ввести код JavaScript и сразу же отобразит результат выполнения.

$ node
> 1 + 1
2
> [-1, -2, -3].map(Math.abs)
[1, 2, 3]
> process.exit(0)
$

process — это глобальный объект в Node, предоставляющий различные способы мониторинга и управления текущим процессом. Метод exit в process может завершить процесс и указать статус выхода (0 для успешного завершения, другое значение для ошибки).

Вы также можете прочитать process.argv для получения аргументов командной строки, переданных сценарию. Этот массив включает команду node и имя сценария, поэтому фактические аргументы начинаются с индекса 2. Если showargv.js содержит только одну строку console.log(process.argv), вы можете запустить его следующим образом:

$ node showargv.js one --and two
["node", "/tmp/showargv.js", "one", "--and", "two"]

Все стандартные глобальные объекты JavaScript, такие как Array, Math и JSON, также доступны в среде Node. Однако функции, связанные с браузерами, такие как document и alert, отсутствуют.

Модули

Помимо некоторых глобальных объектов, таких как console и process, Node добавляет лишь небольшое количество объектов в глобальную область видимости. Если вам нужно получить доступ к другим встроенным функциям, вы можете сделать это через модуль system.

В десятой главе описывается система модулей CommonJS, основанная на функции require. Эта система является встроенной в Node и используется для загрузки всего, от встроенных модулей до загружаемых пакетов и обычных файлов.

При вызове require, Node преобразует заданную строку в файл, который можно загрузить. Путь начинается с /, . или .., он интерпретируется относительно текущего модуля. Таким образом, если вы обращаетесь к файлу /tmp/robot/robot.js и хотите загрузить файл /tmp/robot/graph.js, Node попытается загрузить /tmp/robot/graph.js.

Расширение файла .js может быть проигнорировано, и Node добавит его, если файл существует. Если указанный путь указывает на каталог, Node будет пытаться загрузить файл index.js из этого каталога.

Когда строка, похожая на путь, передаётся в require, она ссылается на встроенный модуль или модуль, установленный в каталоге node_modules. Например, require("fs") предоставит вам встроенный модуль файловой системы Node. А require("robot") может попытаться загрузить библиотеку из каталога node_modules/robot. Один из способов установки такой библиотеки — использование NPM, о котором мы поговорим позже.

Давайте создадим небольшой проект, состоящий из двух файлов. Первый называется main.js и определяет сценарий, который может быть вызван из командной строки для реверсирования строки.

const {reverse} = require("./reverse");

// Index 2 holds the first actual command-line argument
let argument = process.argv[2];

console.log(reverse(argument));

Файл reverse.js определяет библиотеку, содержащую функцию для обращения строк, которую могут использовать этот командный инструмент и другие сценарии, требующие прямого доступа к функции реверса строк.

exports.reverse = function(string) {
  return Array.from(string).reverse().join("");
};

Обратите внимание, что добавление свойств к exports делает их доступными в интерфейсе модуля. Поскольку Node.js рассматривает файлы как модули CommonJS, main.js может получить доступ к экспортированной функции reverse из reverse.js.

Мы можем увидеть результат работы нашего инструмента следующим образом:

$ node main.js JavaScript
tpircSavaJ

Использование NPM для установки

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

Его основная цель — загрузка пакетов. Мы видели пакет ini в десятой главе. Мы можем использовать NPM для получения и установки этого пакета на нашем компьютере.

$ npm install ini
npm WARN enoent ENOENT: no such file or directory,
         open '/tmp/package.json'
+ ini@1.3.5
added 1 package in 0.552s
$ node
> const {parse} = require("ini");
> parse("x = 1\ny = 2");
{ x: '1', y: '2' }

После выполнения команды npm install NPM... Создание каталога node_modules

Будет создан каталог с именем node_modules. В этом каталоге есть каталог ini, который содержит библиотеку. Вы можете открыть его и просмотреть код. Когда мы вызываем require("ini"), загружается эта библиотека, и мы можем вызвать её атрибут parse для анализа файла конфигурации.

По умолчанию NPM устанавливает пакеты в текущем каталоге, а не в центральном расположении. Если вы привыкли к другим менеджерам пакетов, это может показаться необычным, но у него есть преимущество — он позволяет каждому приложению полностью контролировать устанавливаемые им пакеты и упрощает управление версиями и очистку при удалении приложения.

Файл пакета

В примере npm install вы можете увидеть предупреждение о том, что файл package.json не существует. Рекомендуется создать файл для каждого проекта вручную или запустив npm init. Он содержит некоторую информацию о проекте, такую как его имя и версия, а также список его зависимостей.

Из седьмой главы робот-симулятор был модульным в десятой главе, у него мог быть файл package.json, например:

{
  "author": "Marijn Haverbeke",
  "name": "eloquent-javascript-robot",
  "description": "Simulation of a package-delivery robot",
  "version": "1.0.0",
  "main": "run.js",
  "dependencies": {
    "dijkstrajs": "^1.0.1",
    "random-item": "^1.0.0"
  },
  "license": "ISC"
}

Когда вы запускаете npm install, не указывая пакет для установки, NPM установит зависимости, перечисленные в файле package.json. Когда вы устанавливаете пакет, которого нет в списке зависимостей, NPM добавит его в файл package.json.

Версия

Файл package.json перечисляет версию программы и версии её зависимостей. Версия — это способ обработки отдельного развития пакета. Код, написанный для использования пакета в определённый момент времени, может не работать с более новой версией пакета.

NPM требует, чтобы его пакеты следовали руководству по семантическому управлению версиями (semantic versioning), которое кодирует, какие версии пакетов совместимы (не нарушают интерфейс). Семантическая версия состоит из трёх цифр, разделённых точками, например 2.3.0. Каждый раз, когда добавляется новая функция, средняя цифра должна увеличиваться. Каждый раз, когда нарушается совместимость, использование существующего кода пакета может быть несовместимо с новой версией, поэтому необходимо увеличить первую цифру.

Префикс ^ перед номером версии зависимости в файле package.json означает, что можно установить любую версию, совместимую с указанным номером. Например, "^2.3.0" означает, что допустимы любые версии больше или равные 2.3.0 и меньше 3.0.0.

Команда npm также используется для публикации новых пакетов или новых версий пакетов. Если вы запустите npm publish в каталоге, содержащем файл package.json, пакет будет опубликован на сервере регистрации с использованием имени и версии, перечисленных в файле JSON. Любой человек может опубликовать пакет на NPM — но только под новым именем, потому что любой может обновить существующий пакет, что немного пугает.

Поскольку программа npm является программным обеспечением, которое взаимодействует с открытой системой (сервером регистрации пакетов), в ней нет ничего особенного. Другая программа, yarn, доступна для установки с сервера регистрации NPM и использует другой интерфейс и стратегию установки, но выполняет ту же функцию, что и npm.

Эта книга не будет подробно рассматривать использование NPM. Пожалуйста, обратитесь к npmjs.org за дополнительной документацией и информацией о поиске пакетов.

Модуль файловой системы

Наиболее часто используемым встроенным модулем в Node является модуль fs (файловая система). Этот модуль предоставляет функции для работы с файлами и каталогами.

Например, есть функция с именем readFile, которая считывает файл и вызывает обратный вызов, передавая содержимое файла обратному вызову.

let {readFile} = require("fs");
readFile("file.txt", "utf8", (error, text) => {
  if (error) throw error;
  console.log("The file contains:", text);
});

Второй параметр функции readFile указывает кодировку символов, используемую для декодирования файла в строку. Существует множество способов кодирования текстовых данных в двоичные данные, но большинство современных систем используют UTF-8, поэтому, если нет особых причин полагать, что файл использует другую кодировку, чтение файла с использованием "utf-8" является относительно безопасным способом. Если вы не передадите какую-либо кодировку, Node будет считать, что вам нужно проанализировать двоичные данные и вернёт объект Buffer, а не строку. Этот объект похож на массив, где каждый элемент представляет собой байт (8-битное число) файла.

const {readFile} = require("fs");
readFile("file.txt", (error, buffer) => {
  if (err) console.log(`Failed to write file: ${err}`);
  else console.log("File written.");
});

Существует функция с именем writeFile, аналогичная функции readFile, используемая для записи файлов на диск.

const {writeFile} = require("fs");
writeFile("graffiti.txt", "Node was here", err => {
  if (err) console.log(`Failed to write file: ${err}`);
  else console.log("File written.");
});

Здесь нам не нужно указывать кодировку, потому что если мы вызовем writeFile со строкой вместо объекта Buffer, writeFile будет использовать кодировку по умолчанию (то есть UTF-8) для вывода текста.

Модуль fs также содержит другие полезные функции, такие как readdir, которая возвращает массив строк, представляющих файлы в каталоге, stat, которая получает информацию о файле, rename, которая переименовывает файл, и unlink, которая удаляет файл.

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

Для получения дополнительной информации см. документацию на http://nodejs.org/.

Хотя Promise теперь является частью JavaScript, работа по интеграции их с Node.js всё ещё продолжается. Начиная с версии v10, стандартная библиотека включает пакет с именем fs/promises, который экспортирует функции, аналогичные большинству функций fs, но использует Promise, а не обратные вызовы.

const {readFile} = require("fs/promises");
readFile("file.txt", "utf8")
  .then(text => console.log("The file contains:", text));

Иногда вам не нужен асинхронный режим, а требуется блокировка. Многие функции в fs имеют синхронные версии, которые называются так же, как и асинхронные версии, с добавлением Sync в конце. Например, синхронная версия readFile называется readFileSync.

const {readFileSync} = require("fs");
console.log("The file contains:",
            readFileSync("file.txt", "utf8"));

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

HTTP-модуль

Другой важный модуль называется "http". Этот модуль предоставляет функции для запуска HTTP-сервера и создания HTTP-запросов.

Чтобы запустить HTTP-сервер, требуется всего лишь следующий код.

const {createServer} = require("http");
let server = createServer((request, response) => {
  response.writeHead(200, {"Content-Type": "text/html"});
  response.write(`
    <h1>Hello!</h1>
    <p>You asked for <code>${request.url}</code></p>`);
  response.end();
});
server.listen(8000);

Если вы запустите этот скрипт на своём компьютере, вы сможете открыть веб-браузер и перейти по адресу http://localhost:8000/hello, чтобы отправить запрос на ваш сервер. Сервер ответит простым HTML-документом.

Каждый раз, когда клиент пытается подключиться к серверу, сервер вызывает функцию, переданную в качестве параметра функции createServer. Объекты request и response являются связанными объектами, представляющими входные и выходные данные. Объект request содержит информацию о запросе, такую как атрибут url, который представляет URL запроса.

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

Вам нужно вызвать методы объекта response, чтобы отправить некоторые данные обратно клиенту. Первый вызов функции (writeHead) выводит заголовок ответа (см. главу 17). Вам нужно передать статус (в данном случае 200) этой функции. Представленный текст является переводом на русский язык.

Успех) и объект, содержащий информацию о протоколе с заголовком. В этом примере задана "Content-Type"-заголовок, который уведомляет клиента о том, что мы отправим HTML-документ.

Далее используется response.write для отправки тела ответа (самого документа). Если вы хотите отправить соответствующую информацию по частям, вы можете вызвать этот метод несколько раз, например, для отправки данных клиенту. Наконец, вызывается response.end, чтобы отправить сигнал окончания ответа.

Вызов server.listen заставляет сервер ждать запросов на порту 8000. Вот почему вам нужно подключиться к localhost:8000, а не просто к localhost (в этом случае будет использоваться порт по умолчанию, то есть 80).

Когда вы запускаете этот скрипт, процесс остаётся в ожидании. Когда скрипт слушает события — здесь это сетевое соединение — Node не завершает работу автоматически при достижении конца скрипта. Чтобы закрыть его, нажмите Ctrl-C.

Реальному веб-серверу нужно делать гораздо больше, чем показано в этом примере. Разница заключается в том, что нам нужно определить действие, которое клиент пытается выполнить, на основе метода запроса (method), и найти ресурс, обрабатывающий это действие, на основе URL запроса. В следующей главе будут рассмотрены более продвинутые серверы.

Мы можем использовать функцию request модуля http, чтобы действовать как HTTP-клиент.

const {request} = require("http");
let requestStream = request({
  hostname: "eloquentjavascript.net",
  path: "/20_node.html",
  method: "GET",
  headers: {Accept: "text/html"}
}, response => {
  console.log("Server responded with status code",
              response.statusCode);
});
requestStream.end();

Первый параметр функции request — это конфигурация запроса, которая сообщает Node, какой сервер, адрес сервера и метод использовать. Второй параметр — это обратный вызов, который выполняется при запуске ответа. Этот обратный вызов принимает один параметр, используемый для проверки информации об ответе, такой как код состояния.

Как и в случае с объектом response, который мы видели на сервере, возвращаемый объект request позволяет нам использовать метод write для многократной отправки данных и метод end для завершения отправки. В данном примере метод write не используется, поскольку запрос GET не содержит данных в теле запроса.

В модуле https есть аналогичная функция request, которую можно использовать для отправки запросов на адреса https:.

Однако отправлять запросы с помощью собственных функций Node довольно сложно. На NPM есть более удобные пакеты. Например, node-fetch предоставляет интерфейс fetch, основанный на Promise, который похож на тот, что используется в браузерах.

Потоки

В HTTP мы уже видели два примера потоков, которые можно записать: сервер может записывать данные в объект response, а объект запроса, возвращённый функцией request, также может быть записан.

Поток, доступный для записи, — это широко используемая концепция в Node. У этого объекта есть метод write, которому можно передать строку или объект Buffer, чтобы записать некоторые данные в поток. Метод end используется для закрытия потока и может принимать необязательное значение, которое записывается в поток перед его закрытием. Эти два метода также могут принимать обратные вызовы в качестве дополнительных параметров, которые будут вызваны при завершении записи или закрытия.

Также можно использовать createWriteStream из модуля fs для создания выходного потока, направленного на локальный файл. Вы можете вызывать метод write объекта, возвращённого этим методом, каждый раз, когда вы хотите записать часть данных в файл, вместо того чтобы сразу записать все данные, как это делает writeFile.

Читаемые потоки немного сложнее. Обратные вызовы, переданные функции request, которая обрабатывает ответы от сервера, и объекту response, переданному функции request, являются читаемыми потоками (сервер читает запрос и записывает ответ, а клиент сначала записывает запрос, а затем читает ответ). Для чтения потока необходимо использовать обработчики событий, а не методы.

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

У читаемых потоков есть события data и end. Событие data запускается каждый раз при поступлении данных, а событие end запускается, когда поток завершается. Эта модель подходит для «потоковых» данных, которые можно обрабатывать немедленно, даже если весь документ ещё не получен. Мы можем использовать функцию createReadStream, чтобы создать читаемый поток для чтения локального файла.

Этот фрагмент кода создаёт сервер, считывает тело запроса, преобразует полученные данные в верхний регистр и отправляет их обратно клиенту с использованием потока.

const {createServer} = require("http");
createServer((request, response) => {
  response.writeHead(200, {"Content-Type": "text/plain"});
  request.on("data", chunk =>
    response.write(chunk.toString().toUpperCase()));
  request.on("end", () => response.end());
  });
}).listen(8000);

Значение chunk, передаваемое обработчику data, представляет собой двоичный объект Buffer. Мы можем преобразовать его в строку, используя его метод toString, декодируя его в символы UTF-8.

Следующий фрагмент кода, запущенный вместе с сервером выше (который преобразует буквы в верхний регистр), отправляет запрос на сервер и выводит полученный ответ:

const {request} = require("http");
request({
  hostname: "localhost",
  port: 8000,
  method: "POST"
}, response => {
  response.on("data", chunk =>
    process.stdout.write(chunk.toString()));
}).end("Hello server");
// → HELLO SERVER

Этот пример кода записывает данные в process.stdout, который является доступным для записи потоком, вместо использования console.log, потому что console.log добавляет дополнительные символы новой строки после каждой строки вывода, что здесь не подходит.

Файловый сервер

Объединив новые знания об HTTP-серверах и файловых системах, мы создадим мост между ними: HTTP-сервисы позволяют удалённо получать доступ к файловым системам клиентов. Это полезно для сетевых приложений, которым необходимо хранить и совместно использовать данные или предоставлять общий доступ к группе файлов.

Если мы рассматриваем файлы как ресурсы HTTP, методы HTTP GET, PUT и DELETE можно рассматривать как чтение, запись и удаление файлов соответственно. Мы интерпретируем путь запроса как путь к файлу, на который указывает запрос.

Возможно, мы не хотим предоставлять доступ ко всей файловой системе, поэтому мы интерпретируем эти пути как относительные пути, начинающиеся с рабочего пути сервера (то есть пути, с которого был запущен сервер). Если сервер запускается из /home/marijn/public (или C:\Users\marijn\public в Windows), то запрос к /file.txt должен указывать на /home/marijn/public/file.txt (или C:\Users\marijn\public\file.txt).

Мы построим программу поэтапно, используя объект с именем methods, в котором хранятся функции обработки различных методов HTTP. Функции обработки являются async функциями, которые принимают объект запроса в качестве параметра и возвращают Promise, описывающий объект ответа.

const {createServer} = require("http");

const methods = Object.create(null);

createServer((request, response) => {
  let handler = methods[request.method] || notAllowed;
  handler(request)
    .catch(error => {
      if (error.status != null) return error;
      return {body: String(error), status: 500};
    })
    .then(({body, status = 200, type = "text/plain"}) => {
       response.writeHead(status, {"Content-Type": type});
       if (body && body.pipe) body.pipe(response);
       else response.end(body);
    });
}).listen(8000);

async function notAllowed(request) {
  return {
    status: 405,
    body: `Method ${request.method} not allowed.`
  };
}

После запуска этого сервера он всегда будет возвращать ошибку 405. Код этой ошибки означает, что сервер отказывается обрабатывать определённый метод.

При отклонении Promise обработчика ошибок catch преобразует ошибку в объект ответа (если она ещё не является им), чтобы сервер мог вернуть ответ об ошибке, информирующий клиента о том, что он не смог обработать запрос. Поскольку текст запроса содержит код, то перевод будет выглядеть следующим образом:

Поскольку file.txt изначально не существует, поэтому первый запрос завершается неудачно. А PUT-запрос создаёт файл, поэтому мы видим, что следующий запрос может успешно получить этот файл. После использования DELETE-запроса для удаления этого файла, третий GET-запрос снова не находит этот файл.

Этот раздел вкратце

Node — это неплохой небольшой системный инструмент, который позволяет нам запускать JavaScript вне браузера. Первоначальная идея Node заключалась в том, чтобы выполнять сетевые задачи и играть роль узла в сети. Но он также может использоваться для выполнения любых задач сценариев, если вы считаете написание кода на JavaScript приятным занятием, тогда использование Node для автоматизации повседневных задач может быть очень полезным.

NPM предоставляет пакеты для всего, о чём вы можете подумать (и ещё много того, о чём вы не думаете), которые вы можете получить и установить с помощью программы npm. Node также поставляется со множеством встроенных модулей, включая модуль fs (для работы с файловой системой) и модуль http (для запуска HTTP-сервера и создания HTTP-запросов).

Все вводы и выводы в Node являются асинхронными, если только вы явно не используете синхронную разновидность функции, например readFileSync. При вызове асинхронной функции пользователь предоставляет обратный вызов, и Node вызывает их с использованием значений ошибок и результатов (если они есть), когда они готовы.

Задачи

Поисковый инструмент

В системе Unix есть команда grep, которая используется для быстрого поиска регулярных выражений в файле.

Напишите сценарий Node, который можно запустить из командной строки, и который ведёт себя аналогично grep. Он рассматривает свой первый аргумент командной строки как регулярное выражение и любой другой аргумент как файл для поиска. Он должен выводить содержимое любого файла, которое соответствует регулярному выражению.

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

Используйте асинхронные или синхронные функции файловой системы по своему усмотрению. Настройте что-нибудь так, чтобы одновременный запрос нескольких асинхронных операций мог ускорить работу, но не слишком сильно, поскольку большинство файловых систем могут читать только один элемент за раз.

Создание каталогов

Хотя наш метод DELETE в файловом сервере может удалять каталоги (используя rmdir), сервер в настоящее время не предоставляет никакого способа создавать каталоги.

Добавьте поддержку метода MKCOL («make column»), который должен создать каталог, вызывая mkdir модуля fs. MKCOL не является широко используемым методом HTTP, но он имеет аналогичное назначение в стандарте WebDAV, который определяет набор соглашений для создания документов поверх HTTP.

Вы можете использовать функцию, реализующую метод DELETE, в качестве шаблона для метода MKCOL. Если файл не найден, попробуйте создать каталог с помощью mkdir. Если путь содержит каталог, вы можете вернуть ответ 204, чтобы сделать запрос на создание каталога идемпотентным. Если здесь существует некаталогный файл, верните код ошибки. Код 400 («Bad Request», запрос недействителен) подходит.

Общественное пространство в интернете

Поскольку файловый сервер предоставляет услуги для файлов любого типа, даже если он содержит правильный заголовок протокола Content-Type, вы можете использовать его для предоставления услуг веб-сайта. Поскольку эта служба позволяет каждому удалять или заменять файлы, это интересный тип сайта: любой человек может изменять, улучшать и разрушать файлы с помощью правильных HTTP-запросов. Но это всё равно сайт.

Напишите базовую HTML-страницу, содержащую простой файл JavaScript. Поместите этот файл в каталог данных файлового сервера и откройте эти файлы в своём браузере.

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

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

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

Не редактируйте открытый код файлового сервера напрямую, потому что если вы сделаете ошибку, вы, скорее всего, испортите свой код. Вместо этого сохраните свой код вне общедоступного каталога и скопируйте его в общедоступный каталог для тестирования.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/wizardforcel-eloquent-js-3e-zh.git
git@api.gitlife.ru:oschina-mirror/wizardforcel-eloquent-js-3e-zh.git
oschina-mirror
wizardforcel-eloquent-js-3e-zh
wizardforcel-eloquent-js-3e-zh
master