содержание:Начало работы с ядром Node.js (1)
- глобальный объект
- Общий инструмент
- Механизм события
Начало работы с ядром Node.js (2)
- доступ к файловой системе
- HTTP-сервер и клиент
файловая система фс
Модуль fs представляет собой инкапсуляцию файловых операций. Он обеспечивает операции файловой системы POSIX, такие как чтение, запись, переименование, удаление, обход каталогов и ссылок. Все методы имеют асинхронную и синхронную формы. Последний параметр асинхронного метода — это функция обратного вызова. Параметры, передаваемые функции обратного вызова, зависят от конкретного метода, но первый параметр функции обратного вызова зарезервирован для исключения. Если операция завершилась успешно, первый параметр будет нулевым или неопределенным.
const fs = require('fs');
fs.unlink('/tmp/hello', (err) => {
if (err) throw err;
console.log('成功删除 /tmp/hello');
});
При использовании синхронизированных методов любые исключения генерируются немедленно. Исключения можно обрабатывать с помощью try/catch или всплывать.
const fs = require('fs');
fs.unlinkSync('/tmp/hello');
console.log('成功删除 /tmp/hello');
1.fs.readFile(path,[options], callback)
fs.readFile(path,[options], callback) 是最简单的读取。它接受一个必选参数filename,表示要读取的文件名。第二个参数options是可选的,表示文件的字符编码。 callback是回调函数,用于接收文件的内容。如果不指定options,则 callback 就是第二个参数。回调函数提供两个参数 err和data,err表示有没有错误发生,data是文件内容。如果指定了options, data 是一个解析后的字符串,否则data将会是以Buffer形式表示的二进制数据。 Например:
fs.readFile('/etc/passwd', 'utf8', callback);
Следует отметить, что когда путь является каталогом, поведение fs.readFile() и fs.readFileSync() зависит от платформы. В macOS, Linux и Windows вернет ошибку. Во FreeBSD он возвращает содержимое представления каталога.
// 在 macOS、Linux 与 Windows 上:
fs.readFile('<directory>', (err, data) => {
// => [Error: EISDIR: illegal operation on a directory, read <directory>]
});
// 在 FreeBSD 上:
fs.readFile('<directory>', (err, data) => {
// => null, <data>
});
2.fs.readFileSync(path[, options])
fs.readFileSync(имя файла,[кодировка]) — это синхронизированная версия fs.readFile. Он принимает те же параметры, что и fs.readFile, но содержимое прочитанного файла будет возвращено в виде возвращаемого функцией значения. Если произойдет ошибка, fs выдаст исключение, тогда нам нужно использовать try и catch, чтобы поймать и обработать исключение.
3.fs.open(path, flags[, mode], callback)
fs.open(path, flags[ mode], callback) — это функция открытия POSIX. Инкапсуляция, аналогичная функции fopen в стандартной библиотеке языка C. Он принимает два обязательных параметра, путь — это путь к файлу, а флаги могут принимать следующие значения:
'r' - 以读取模式打开文件。如果文件不存在则发生异常。
'r+' - 以读写模式打开文件。如果文件不存在则发生异常。
'rs+' - 以同步读写模式打开文件。命令操作系统绕过本地文件系统缓存。
(这对 NFS 挂载模式下打开文件很有用,因为它可以让你跳过潜在的旧本地缓存。 它对 I/O 的性能有明显的影响,所以除非需要,否则不要使用此标志。
注意,这不会使 fs.open() 进入同步阻塞调用。 如果那是你想要的,则应该使用 fs.openSync()。)
'w' - 以写入模式打开文件。文件会被创建(如果文件不存在)或截断(如果文件存在)。
'wx' - 类似 'w',但如果 path 存在,则失败。
'w+' - 以读写模式打开文件。文件会被创建(如果文件不存在)或截断(如果文件存在)。
'wx+' - 类似 'w+',但如果 path 存在,则失败。
'a' - 以追加模式打开文件。如果文件不存在,则会被创建。
'ax' - 类似于 'a',但如果 path 存在,则失败。
'a+' - 以读取和追加模式打开文件。如果文件不存在,则会被创建。
'ax+' - 类似于 'a+',但如果 path 存在,则失败。
mode устанавливает режим файла (разрешения и закрепленные биты), но только при создании файла. По умолчанию 0o666, доступен для чтения и записи.
4.fs.read(fd, buffer, offset, length, position, callback)
fs.read(fd, buffer, offset, length, position, callback) — это инкапсуляция функции чтения POSIX, которая предоставляет интерфейс более низкого уровня, чем fs.readFile. Прочитать данные из файла, указанного fd. буфер — это буфер, в который будут записываться данные. offset — это смещение в буфере, с которого начинается запись. length — целое число, указывающее количество байтов для чтения. position указывает позицию для начала чтения из файла. Если position равно null, данные будут считаны из текущей позиции чтения файла, и позиция чтения файла будет обновлена. Если position является целым числом, позиция чтения файла остается неизменной. Обратный вызов имеет три параметра (err, bytesRead, buffer).
var fs = require('fs');
fs.open('content.txt', 'r', function(err, fd) {
if (err) {
console.error(err);
return;
}
var buf = new Buffer(8);
fs.read(fd, buf, 0, 8, null, function(err, bytesRead, buffer) {
if (err) {
console.error(err);
return;
}
console.log('bytesRead: ' + bytesRead);
console.log(buffer);
})
});
выход:
bytesRead: 8
<Buffer 54 65 78 74 20 e6 96 87>
HTTP-сервер и клиент
Node.js Библиотека предоставляет HTTP-модуль, который инкапсулирует эффективный простой HTTP-сервер и клиент HTTP. http.server - это HTTP-сервер на основе событий, его ядро по базовому C ++ Node.js Частично достигается, JavaScript и интерфейсной пакетом с учетом высокой производительности и простоты. http.request HTTP - это клиентский инструмент для инициирования запроса на сервер HTTP, или реализован, например, для выбора содержимого Pingback.
Интерфейс HTTP в Node.js предназначен для поддержки многих функций протокола. Например, сообщения, закодированные фрагментами. Эти интерфейсы не буферизуют полные запросы или ответы, и пользователи могут обрабатывать данные в потоке. Заголовок сообщения HTTP представлен объектом, где имя ключа написано в нижнем регистре, а значение ключа не может быть изменено:
{ 'content-length': '123',
'content-type': 'text/plain',
'connection': 'keep-alive',
'host': 'mysite.com',
'accept': '*/*' }
Чтобы поддерживать все возможные HTTP-приложения, HTTP API Node.js очень низкоуровневый. Он имеет дело только с потоковой обработкой и разбором сообщений. Он разбирает сообщение на заголовки и тела сообщений, но не анализирует конкретные заголовки или тела сообщений. Имя ключа пишется строчными буквами, а значение ключа нельзя изменить. Чтобы поддерживать все возможные HTTP-приложения, HTTP API Node.js очень низкоуровневый. Он имеет дело только с потоковой обработкой и разбором сообщений. Он разбирает сообщение на заголовки и тела сообщений, но не анализирует конкретные заголовки или тела сообщений.
HTTP-сервер
http.Server — это объект HTTP-сервера в модуле http.Все системы на основе HTTP, созданные с помощью Node.js, такие как веб-сайты, социальные приложения и даже прокси-серверы, реализованы на основе http.Server. Он предоставляет набор API с очень низким уровнем инкапсуляции, только управление потоком и простое обучение и синтаксический анализ, а все расширенные функции реализованы через его интерфейсы. Например, этот пример на официальном сайте:
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
})
В этом коде http.createServer([requestListener]) используется для создания нового экземпляра http.Server. Теперь давайте посмотрим на http.createServer([requestListener]).
1. События http.Server
http.Server — это HTTP-сервер, основанный на событиях.Все запросы инкапсулируются как независимые события.Для реализации всех функций HTTP-сервера разработчикам нужно только написать функции ответа на его события. он наследует от EventEmitter , который предоставляет следующие события:
- request: Запускается каждый раз при получении запроса. Обратите внимание, что на одно соединение может быть несколько запросов (в случае HTTP-соединений проверки активности).
- connection : Запускается, когда устанавливается новый поток TCP. socket — это объект типа net.Socket. Обычно пользователям не требуется доступ к этому событию. Обратите внимание, что сокеты не генерируют «читаемые» события из-за того, как синтаксический анализатор протокола привязан к сокету. Доступ к сокетам также можно получить через request.connection.
- connect: запускается всякий раз, когда клиент отправляет HTTP-запрос CONNECT. Если событие не прослушивается, клиент, отправляющий запрос CONNECT, закроет соединение. Когда это событие запускается, в запрошенном сокете нет прослушивателя событий «данные», что означает, что прослушиватель событий «данные» должен быть связан для обработки данных, отправленных на сервер в сокете.
- close: это событие запускается, когда сервер закрывается. Обратите внимание, что не когда пользователь отключен, а когда сервер не работает.
Чаще всего в этих событиях используется наиболее часто используемый запрос, поэтому http предоставляет ярлык: http.createServer([requestListener]) , функция заключается в создании HTTP-сервера и использовании requestListener в качестве функции прослушивания событий запроса. Это пример нашего официального сайта выше, на самом деле его явный метод реализации выглядит следующим образом:
//httpserver.js
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = new http.Server();
server.on('request', (req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
})
2. http.ServerRequest
http.ServerRequest — это информация HTTP-запроса, которая наиболее важна для внутренних разработчиков. Обычно он отправляется событием запроса http.Server и передается в качестве первого параметра, обычно называемого запросом, или HTTP-запрос, как правило, может быть разделен на две части: заголовок запроса и тело запроса. Приведенный выше контент может быть прочитан сразу после завершения синтаксического анализа заголовка запроса из-за его небольшой длины. Тело запроса может быть относительно длинным, и для его передачи может потребоваться определенное время, поэтому http.ServerRequest предоставляет следующие три события для управления передачей тела запроса. требование HTTP-запросы обычно можно разделить на две части: заголовок запроса (RequestHeader) и тело запроса (RequestBody). Приведенный выше контент может быть прочитан сразу после завершения синтаксического анализа заголовка запроса из-за его небольшой длины. Тело запроса может быть относительно длинным, и для его передачи может потребоваться определенное время, поэтому http.ServerRequest предоставляет следующие три события для управления передачей тела запроса. http.ServerRequest предоставляет 3 события для управления передачей тела запроса:
-
Данные: Объемные данные При поступающих запроса событие срабатывает, обеспечивая параметр к функции обратного вызова, полученные данные, событие можно назвать несколько раз (все данные в соответствии с набором данных последовательных томов запрашиваются). Если событие не контролируется, тело запроса будет заброшено;
-
end: это событие срабатывает, когда данные тела запроса заполнены. После этого событие данных больше не запускается;
-
закрыть: это событие запускается, когда текущий запрос пользователя заканчивается. В отличие от end, если пользователь принудительно завершает передачу, close все равно вызывается.
表4-2 ServerRequest 的属性 名 称 含 义 complete 客户端请求是否已经发送完成 httpVersion HTTP 协议版本,通常是 1.0 或 1.1 method HTTP 请求方法,如 GET、POST、PUT、DELETE 等 url 原始的请求路径,例如 /static/image/x.jpg 或 /user?name=byvoid headers HTTP 请求头 trailers HTTP 请求尾(不常见) connection 当前 HTTP 连接套接字,为 net.Socket 的实例 socket connection 属性的别名 client client 属性的别名
3. Получите содержимое запроса GET
Обратите внимание, что в http.ServerRequest нет свойств, аналогичных тем, что есть в языке PHP._POST, запросы GET встраиваются прямо в путь. URL-адрес представляет собой полный путь запроса (включая часть после ?), поэтому содержимое после него анализируется вручную как параметр запроса GET. Функция разбора в модуле URL-адреса Node.js предоставляет эту функциональность.
Возьмите URL: http://127.0.0.1/user?name=byvoid&email=byvoid@byvoid.com в качестве примера:
var http = require("http");
var url = require("url");
var server = new http.Server();
server.on("request", function (req, res) {
if (req.url == "/favicon.ico") {
return;
}
var m = url.parse(req.url, true);
console.log(m)
res.writeHead(200, {'Content-type': 'text/html;charset = utf8'});
res.end();
})
server.listen(80);
console.log("The server begin");
Вывод Console.log:
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search:'?name=byvoid&email=byvoid@byvoid.com',
query: { name: 'byvoid', email:'byvoid@byvoid.com' },
pathname: '/user',
path:'/user?name=byvoid&email=byvoid@byvoid.com',
href:'/user?name=byvoid&email=byvoid@byvoid.com'
}
4. Опубликовать запросы на получение контента
Протокол HTTP версии 1.1 предоставляет 8 стандартных методов запроса, наиболее распространенными из которых являются GET и POST. По сравнению с запросом GET, который кодирует все содержимое в пути доступа, все содержимое запроса POST находится в теле запроса. http.ServerRequest не имеет содержимого свойства в тексте запроса, поскольку ожидание передачи тела запроса может занять много времени, например, загрузка файла. Во многих случаях нам может не понадобиться обращать внимание на содержимое тела запроса и вредоносный POST. Запросы могут потреблять много ресурсов сервера. Таким образом, Node.js не будет анализировать тело запроса по умолчанию, поэтому, когда нам это нужно, мы должны написать его вручную Конкретный метод реализации выглядит следующим образом:
var http = require('http');
var querystring = require('querystring');
var util = require('util');
http.createServer(function(req, res) {
var post = '';
req.on('data', function(chunk) {
post += chunk;
});
req.on('end', function() {
post = querystring.parse(post);
res.end(util.inspect(post));
});
}).listen(3000);
5.http.ServerResponse
http.ServerResponse — это информация, возвращаемая клиенту, которая определяет окончательный результат, который может увидеть пользователь. Он также отправляется событием запроса http.Server, передаваемым в качестве второго параметра, обычно называемого ответ или рез. http.ServerResponse имеет три важные функции-члены для возврата заголовков ответа, содержимого ответа и завершения запроса:
- response.writeHead(statusCode, [headers]): отправить заголовки ответа запрашивающему клиенту. statusCode — это код состояния HTTP, например 200 (запрос выполнен успешно), 404 (не найдено) и т. д. headers — это ассоциативный массивоподобный объект, представляющий каждое свойство заголовков ответов. Эта функция может быть вызвана в запросе не более одного раза. Если она не вызывается, заголовок ответа будет сгенерирован автоматически.
- response.write(data, [encoding]): отправить содержимое ответа запрашивающему клиенту. data — это буфер или строка, представляющая, что отправлять. Если данные являются строкой, необходимо указать encoding для указания метода кодирования, по умолчанию используется utf-8 . response.write может вызываться несколько раз, прежде чем будет вызван response.end.
- response.end([data], [encoding]): завершает ответ, сообщая клиенту, что вся отправка завершена. Эта функция должна быть вызвана один раз, когда весь возвращаемый контент отправлен. Он принимает два необязательных параметра с тем же значением, что и response.write. Если эта функция не вызывается, клиент навсегда останется в состоянии ожидания.
HTTP-клиент
Модуль http предоставляет две функции http.request и http.get, которые функционируют как клиент для инициирования запроса к HTTP-серверу.
1.http.request(options,callback)
http.request(options, callback) инициирует HTTP-запрос, который принимает два параметра, option — это объект, похожий на ассоциативный массив, представляющий параметры запроса, а callback — это функция обратного вызова запроса. Обычно используемые параметры опциона следующие:
- host : доменное имя или IP-адрес запрашивающего веб-сайта.
- порт: порт для запроса веб-сайта, по умолчанию 80.
- method : метод запроса, по умолчанию — GET.
- path : запрошенный путь относительно корня, по умолчанию "/". QueryString должен быть включен в него. Например, /search?query=byvoid .
- headers : Объект ассоциативного массива, содержащий содержимое заголовков запроса.
Обратный вызов передает параметр, который является экземпляром http.ClientResponse. http.request возвращает экземпляр http.ClientRequest, вот код для отправки запроса POST через http.request:
var http = require('http');
var querystring = require('querystring');
var contents = querystring.stringify({
name: 'byvoid',
email: 'byvoid@byvoid.com',
address: 'Zijing 2#, Tsinghua University',
});
var options = {
host: 'www.byvoid.com',
path: '/application/node/post.php',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length' : contents.length
}
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (data) {
console.log(data);
});
});
req.write(contents);
req.end();
Результаты приведены ниже:
array(3) {
["name"]=>
string(6) "byvoid"
["email"]=>
string(17) "byvoid@byvoid.com"
["address"]=>
string(30) "Zijing 2#, Tsinghua University"
}
2.http.get(options, callback)
Модуль http также предоставляет более простой метод обработки запросов GET: http.get(options, callback). Это упрощенная версия http.request, с той лишь разницей, что http.get автоматически устанавливает метод запроса на GET Request, и нет необходимости вручную вызывать req.end() :
var http = require('http');
http.get({host: 'www.byvoid.com'}, function(res) {
res.setEncoding('utf8');
res.on('data', function (data) {
console.log(data);
});
});
http.ClientRequest
Этот объект создается и возвращается внутри http.request(). Он представляет собой запрос на обработку, заголовки которого поставлены в очередь. Он предоставляет событие ответа, то есть объект привязки функции обратного вызова, указанный вторым параметром http.request или http.get.
var http = require('http');
var req = http.get({host: 'www.byvoid.com'});
req.on('response', function(res) {
res.setEncoding('utf8');
res.on('data', function (data) {
console.log(data);
});
});
Как и http.ServerResponse, http.ClientRequest также предоставляет функции записи и завершения для отправки тела запроса на сервер, обычно для операций POST, PUT и других. После всего написания необходимо вызвать конечную функцию, чтобы уведомить сервер, иначе запрос недействителен. http.ClientRequest также предоставляет следующие часто используемые функции:
- request.abort() : пометить запрос как прерванный. Вызов этого метода приведет к отбрасыванию оставшихся данных в ответе и разрушению сокета.
- request.setTimeout(timeout,[callback]): Установите время ожидания запроса, время ожидания — количество миллисекунд. Как только сокет будет выделен для запроса и подключен, будет вызван socket.setTimeout().
- request.end([data[ encoding]][ callback]) завершает отправку запроса. Если части тела запроса не были отправлены, они сбрасываются в поток. Если запрос разделен на части, отправляется завершающий символ '0\r\n\r\n'.
http.ClientResponse
Подобно http.ServerRequest, http.ClientResponse предоставляет три события, данные, конец и закрытие, которые запускаются, когда данные поступают, передача завершается и соединение завершается соответственно.Событие данных передает фрагмент параметра, который представляет полученные данные.
http.ClientResponse также предоставляет некоторые свойства для указания статуса результата запроса:
statusCode HTTP 状态码,如 200、404、500
httpVersion HTTP 协议版本,通常是 1.0 或 1.1
headers HTTP 请求头
trailers HTTP 请求尾(不常见)
http.ClientResponse также предоставляет следующие специальные функции:
- response.setEncoding([encoding]): установить кодировку по умолчанию.При запуске события данных данные будут закодированы в кодировке. Значение по умолчанию равно null, то есть без кодировки, сохраненной в виде буфера. Распространенная кодировка — utf8.
- response.pause(): приостановить получение данных и отправку событий, чтобы упростить функцию загрузки.
- Response.Resume (): резюме из пауза.