Как и в случае с любыми другими приложениями, при написании приложений Node приходится решать сложные проблемы.
В этой статье мы рассмотрим некоторые решения распространенных проблем при написании приложений Node.
Зарегистрируйте вывод команды установки npm
Чтобы записать вывод команды npm install
, мы можем направить stderr в stdout.
Например, мы можем написать:
npm install 2>&1 | tee log.txt
2>&1
перенаправляет stderr на stdout.
tee
читает стандартный вывод и записывает его как в стандартный вывод, так и в один или несколько файлов.
Мы пишем в log.txt
, как указано в команде.
Разбор страниц с помощью Node.js и XPath
Чтобы проанализировать HTML с помощью XPath, мы анализируем HTML с помощью parse5
.
Он не анализирует его в объект DOM, но он быстрый и совместим с W3C.
Мы можем сериализовать его в XHTML с помощью xmlserializer
,
Затем можно использовать xmldom
для получения DOM.
И мы используем библиотеку xpath
для выполнения наших запросов XPath.
Например, мы можем написать:
const fs = require('mz/fs'); const xpath = require('xpath'); const parse5 = require('parse5'); const xmlSer = require('xmlserializer'); const DOMParser = require('xmldom').DOMParser; (async () => { const html = await fs.readFile('./foo.html'); const document = parse5.parse(html.toString()); const xhtml = xmlSer.serializeToString(document); const doc = new DOMParser().parseFromString(xhtml); const select = xpath.useNamespaces({ x: "http://www.w3.org/1999/xhtml" }); const nodes = select("/html/body/header/div/div[1]/a[2]", doc); console.log(nodes); })();
Мы импортируем библиотеку fs
для чтения файла foo.htmk
.
Затем мы анализируем документ с parse5
на объект document
.
Затем мы преобразуем HTML в XHTML с помощью метода xmlserializer
serializeToString
.
Затем мы создаем новый экземпляр DOMParser
, анализируя преобразованную строку.
Затем мы создаем объект select
с помощью метода userNamespace
, чтобы мы могли выбирать элементы DOM с помощью XPath.
Затем мы вызываем select
для выбора элементов с помощью XPath.
doc
- это объект DOM, возвращенный из DOMParser
.
nodes
имеет возвращенные узлы.
Кроме того, мы можем использовать библиотеку libxmljs
для получения узлов с помощью XPath.
Например, мы можем написать:
const libxmljs = require("libxmljs"); const xml = ` <?xml version="1.0" encoding="UTF-8"?>' <root> <child foo="bar"> <grandchild baz="foo">some content</grandchild> </child> <sibling>with content!</sibling> </root>`; const xmlDoc = libxmljs.parseXml(xml); const gchild = xmlDoc.get('//grandchild'); console.log(gchild.text())
Мы используем libxmljs
, передавая строку XML методу parsXml
.
Затем мы передаем строку XPath методу get
, чтобы получить элемент.
И text
будет содержать текст для выбранного узла, то есть some content
.
Ошибка записи после завершения на веб-сервере Node.js
Если мы используем модуль net
для создания веб-сервера, тогда, когда мы пишем сообщение, мы должны передать обратный вызов в качестве второго аргумента для вызова end
на нем.
Например, мы можем написать:
const netSocket = require('net').Socket(); netSocket.connect(9090); netSocket.write('hello', err => netSocket.end());
Мы вызываем netSocket.end()
в обратном вызове второго аргумента, чтобы закрыть сокет после записи сообщения.
Мы должны это сделать, потому что write
асинхронный. Нет гарантии, что write
будет выполнено до end
, поскольку мы не передадим его в обратный вызов.
Так что-то вроде:
const netSocket = require('net').Socket(); netSocket.connect(9090); netSocket.write('hello'); netSocket.end();
приведет к ошибке «написать после окончания».
Разница между response.setHeader и response.writeHead
response.setHeader
позволяет нам установить один заголовок для неявных заголовков.
Если заголовок уже существует, то его значение будет заменено.
Мы можем использовать массив строк для отправки нескольких заголовков с одним и тем же именем.
response.writeHead
отправляет заголовок ответа на запрос.
Один метод принимает объект с кодом состояния и заголовками ответа.
Чтобы использовать setHeader
, мы можем написать:
const body = "hello world"; response.setHeader("Content-Length", body.length); response.setHeader("Content-Type", "text/plain"); response.setHeader("Set-Cookie", "type=foo"); response.status(200);
Мы устанавливаем один заголовок ответа с одним setHeader
вызовом.
Код состояния устанавливается отдельно с response.status
.
С другой стороны, с writeHead
мы одновременно устанавливаем коды состояния и заголовки ответа.
Например, мы можем написать:
const body = "hello world"; response.writeHead(200, { "Content-Length": body.length, "Content-Type": "text/plain", "Set-Cookie": "type=foo" });
Мы устанавливаем код состояния ответа в первом аргументе и все заголовки ответа в объекте во втором аргументе.
Заключение
response.setHeader
и response.writeHead
разные.
Мы можем анализировать HTML или XML и использовать XPath для запроса узлов.
Чтобы завершить сокет, созданный с помощью net
, мы должны вызвать его в обратном вызове, переданном во второй аргумент write
.
Мы можем записать npm install
ошибки в файл, перенаправив вывод.