INTEGRITY Документация

HTMLRewriter

Контекст

HTMLRewriter класс позволяет разработчикам создавать полноценные и выразительные HTML парсеры внутри приложения Cloudflare Workers. Его можно рассматривать как аналог jQuery прямо внутри вашего Workers приложения. Опираясь на мощный JavaScript API для разбора и преобразования HTML, HTMLRewriter позволяет разработчикам создавать функционально насыщенные приложения.

HTMLRewriter класс следует инстанцировать один раз в вашем Workers скрипте, присоединив ряд обработчиков с помощью on и onDocument функции.


Конструктор

new HTMLRewriter()
	.on("*", new ElementHandler())
	.onDocument(new DocumentHandler());

Глобальные типы

На протяжении HTMLRewriter API есть несколько стандартных типов, которые используются во многих свойствах и методах:


Обработчики

Есть два типа обработчиков, которые можно использовать с HTMLRewriter: обработчики элементов и обработчики документов.

Element Handlers

Обработчик элементов реагирует на любой входящий элемент, если подключён с помощью .on функцию у HTMLRewriter экземпляр. Обработчик элемента должен реагировать на element, comments, а также text. В примере обрабатывается div элементов с ElementHandler в качестве класса.

class ElementHandler {
	element(element) {
		// An incoming element, such as `div`
		console.log(`Incoming element: ${element.tagName}`);
	}

	comments(comment) {
		// An incoming comment
	}

	text(text) {
		// An incoming piece of text
	}
}

async function handleRequest(req) {
	const res = await fetch(req);

	return new HTMLRewriter().on("div", new ElementHandler()).transform(res);
}

Обработчики документа

Обработчик документа представляет входящий HTML документ. В обработчике документа можно определить ряд функций для запроса и изменения его doctype, comments, text, а также end. В отличие от обработчика элемента, у обработчика документа doctype, comments, text, а также end функции не ограничены конкретным селектором. Функции обработчика документа вызываются для всего содержимого страницы, включая содержимое за пределами тега верхнего уровня HTML:

class DocumentHandler {
	doctype(doctype) {
		// An incoming doctype, such as <!DOCTYPE html>
	}

	comments(comment) {
		// An incoming comment
	}

	text(text) {
		// An incoming piece of text
	}

	end(end) {
		// The end of the document
	}
}

Асинхронные обработчики

Все функции, определённые как в обработчиках элементов, так и в обработчиках документа, могут возвращать либо void или Promise<void>. Если сделать функцию-обработчик async позволяет обращаться к внешним ресурсам, например к API через fetch, к Workers KV, Durable Objects или кешу.

class UserElementHandler {
	async element(element) {
		let response = await fetch(new Request("/user"));

		// fill in user info using response
	}
}

async function handleRequest(req) {
	const res = await fetch(req);

	// run the user element handler via HTMLRewriter on a div with ID `user_info`
	return new HTMLRewriter()
		.on("div#user_info", new UserElementHandler())
		.transform(res);
}

Элемент

element аргумент, используемый только в обработчиках элементов, представляет собой представление DOM-элемента. У элемента есть ряд методов для его изучения и изменения:

Свойства

Методы

EndTag

endTag аргумент, используемый только в обработчиках, зарегистрированных с помощью element.onEndTag, является ограниченным представлением элемента DOM.

Свойства

Методы

Текстовые фрагменты

Поскольку Cloudflare выполняет потоковый парсинг без копирования (zero-copy), текстовые фрагменты не совпадают с текстовыми узлами лексического дерева. Один текстовый узел лексического дерева может быть представлен несколькими фрагментами по мере их поступления от источника по сети.

Рассмотрим следующую разметку: <div>Hey. How are you?</div>. Возможно, что скрипт Workers не получит весь текстовый узел от источника целиком за один раз, вместо этого text обработчик элемента будет вызываться для каждой полученной части текстового узла. Например, обработчик может быть вызван с "Hey. How ", затем "are you?". Когда приходит последний chunk, у текста lastInTextNode свойство будет установлено в true. Разработчикам следует объединять эти chunks между собой.

Свойства

Методы

Комментарии

comments функция обработчика элемента позволяет разработчикам запрашивать HTML-комментарии и управлять ими.

class ElementHandler {
	comments(comment) {
		// An incoming comment element, such as <!-- My comment -->
	}
}

Свойства

Методы

Doctype

doctype функция обработчика документа позволяет разработчикам запрашивать doctype.

class DocumentHandler {
	doctype(doctype) {
		// An incoming doctype element, such as
		// <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
	}
}

Свойства

Конец

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

class DocumentHandler {
	end(end) {
		// The end of the document
	}
}

Методы


Селекторы

Вот что такое селекторы и для чего они используются.


Ошибки

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

async function handle(request) {
	let oldResponse = await fetch(request);
	let newResponse = new HTMLRewriter()
		.on("*", {
			element(element) {
				throw new Error("A really bad error.");
			},
		})
		.transform(oldResponse);

	// At this point, an expression like `await newResponse.text()`
	// will throw `new Error("A really bad error.")`.
	// Thereafter, any use of `newResponse.body` will throw the same error,
	// and `oldResponse.body` will be closed.

	// Alternatively, this will produce a truncated response to the client:
	return newResponse;
}