A API HTMLStream processa dados de streaming HTML nos pontos de presença (POPs) e os transmite em blocos para acelerar a entrega.
Visão geral
O Edge Routine lida com cenários de frontend em que os POPs enviam dados especiais, como cabeçalhos User-Agent, localizações geográficas e endereços IP. Em alguns casos, é necessário modificar o fluxo da página HTML em tempo real nos POPs. Parsers ad hoc baseados em regex são propensos a erros e não oferecem suporte a streaming. Parsers open-source, como parse5 e htmlparser2, consomem memória excessiva. O Edge Routine resolve esse problema com um parser nativo de processamento de fluxo para modificar HTML nos POPs.
O parser é integrado ao Edge Routine e não se baseia em padrões web.
Exemplo
-
Cenário
Para modificar todas as tags de âncora
<a/>em uma página HTML e vinculá-las ahttp://www.taobao.com, use o código do Edge Routine a seguir. -
Código de exemplo
async function handleRequest(request) { // 1. In this example, the HTML page that you want to modify is returned. const response = await fetch("http://www.example.com"); // 2. Configure the stream processing-based parser to manage HTML content. The parser supports multiple CSS selectors. // Specify the method for capturing the syntax and register a callback function for rewriting. const htmlStream = new HTMLStream( response.body, // Specify the HTML flow that you want to modify. [[ "a", // The element selector. This specifies that all the anchor tags are selected. { // Register a callback function. The element callback function can be called in the anchor tags or in the element nodes of the Document Object Model (DOM) API. // In the callback function, you can change the event object (e). element: function(e) { // Modify the href attribute. e.setAttribute("href", "http://www.taobao.com"); } } ]]); // 3. Return the modified request to the browser. HTMLStream is a readable stream. // You can use HTMLStream in all scenarios that support ReadableStream. return new Response(htmlStream); } export default { async fetch(request) { return handleRequest(request); } }; -
Análise do resultado
O código de exemplo modifica um fluxo HTML em tempo real com a API HTMLStream. O HTMLStream funciona da seguinte maneira:
A Fetch API recupera uma expressão de fluxo para a requisição. O Edge Routine pode ainda não ter recuperado o corpo da resposta, o que reduz a coleta de lixo proveniente do buffer de dados.
-
O HTMLStream é um fluxo compatível com TransformStream. Ele chama funções de callback de reescrita para modificar páginas HTML em tempo real. Passe o fluxo de dados brutos para o fluxo HTMLStream conforme mostrado na Etapa 2 do código de exemplo.
O primeiro parâmetro é um fluxo que representa os dados HTML brutos.
-
O segundo parâmetro é um array de rewriters. Cada rewriter é um array de dois elementos: uma string de seletor e um objeto de callback. No exemplo,
["a" , {....}]declara um rewriter onde "a" seleciona todas as tags de âncora. O objeto de callback pode conter as seguintes funções:element: function(e). Chamada quando os elementos correspondentes são analisados.comments: function(e). Chamada quando comentários aninhados nos elementos correspondentes são analisados.text: function(e). Chamada quando o texto nos elementos correspondentes é analisado. Pode ser chamada várias vezes porque o HTMLStream processa o texto em blocos.
Diferentemente do parse5 e do htmlparser2, o HTMLStream não armazena dados em buffer nem gera uma árvore DOM. Isso reduz o tempo de processamento e o consumo de memória, permitindo alto throughput e concorrência na análise de HTML.
Rewriter
Um rewriter registra o alvo a ser reescrito. Trata-se de um array de dois elementos.
-
O primeiro elemento deve ser uma string ou null.
String: um seletor de elemento que localiza um elemento ou tag específica.
-
null: aplica o rewriter a todo o documento.
NotaUm rewriter no nível do documento não consegue localizar elementos individuais. Use-o apenas quando precisar processar o documento inteiro.
-
O segundo elemento deve ser um objeto JavaScript contendo as funções de callback registradas.
Com um seletor de elemento, trata-se do objeto de callback de elemento. Com um seletor de documento, trata-se do objeto de callback de documento.
Uma operação HTMLStream aceita múltiplos seletores de elemento, mas apenas um seletor de documento.
Sintaxe dos seletores de elemento
A sintaxe do seletor de elemento é um subconjunto dos seletores CSS. A linguagem de programação de um seletor de elemento pode diferir da de um seletor CSS. Padrões suportados:
*: seleciona todos os elementos.div: seleciona a tagdiv. Suporta tags HTML e personalizadas.E#id: seleciona o elemento E com oidespecificado.E.Class: seleciona o elemento E com aClassespecificada.E[attr]: seleciona o elemento E que possui o atributo attr.-
Atributos de elemento:
E[attr="a"]: seleciona o elemento E onde attr é igual a a (diferencia maiúsculas de minúsculas).E[attr^="a"]: seleciona o elemento E onde attr é igual a a (não diferencia maiúsculas de minúsculas).E[attr$="a"]: seleciona o elemento E onde attr termina com a.E[attr^="a"]: seleciona o elemento E onde attr começa com a.E[attr*="a"]: seleciona o elemento E onde attr contém a.E[attr|="a"]: seleciona o elemento E onde attr começa com a- (valores separados por hífen, como en-ch, en-us).
-
Ordem entre elementos:
E F: seleciona o elemento F descendente do elemento E.E > F: seleciona o elemento F filho direto do elemento E.
E:not(S): seleciona o elemento E somente quando o seletor S não corresponde.
Funções de callback para seletores de elemento
Os seletores de elemento aceitam as seguintes funções de callback:
|
Função de callback |
Descrição |
Assinatura da função de callback |
|
element |
Função de callback não assíncrona chamada após a análise completa dos elementos correspondentes. |
A assinatura da função de callback é function(e). Esta assinatura está presente no objeto Element. Para mais informações, consulte Element. |
|
comments |
Função de callback não assíncrona chamada quando existem comentários nos elementos correspondentes. |
A assinatura da função de callback é function(e). Esta assinatura está presente no objeto Comments. Para mais informações, consulte Comments. |
|
text |
Função de callback não assíncrona chamada quando o texto analisado é retornado. Pode ser invocada múltiplas vezes devido ao processamento em blocos. |
A assinatura da função de callback é function(e). Esta assinatura está presente no objeto TextChunk. Para mais informações, consulte TextChunk. Nota
Este callback pode ser chamado várias vezes. O HTMLStream lê o texto em blocos e invoca esta função para cada bloco. Una todos os blocos para obter o texto completo. |
Um seletor de elemento pode omitir todas as funções de callback. Nesse caso, os elementos correspondentes são gerados sem modificações. Registre apenas os callbacks necessários.
Seletor de documento
Um seletor de documento tem como alvo o documento inteiro. Defina o primeiro elemento no array do rewriter como null. Apenas um seletor de documento é permitido por operação HTMLStream.
Funções de callback para seletores de documento
Os seletores de documento aceitam callbacks semelhantes aos seletores de elemento:
|
Função de callback |
Descrição |
Assinatura da função de callback |
|
doctype |
Função de callback não assíncrona chamada quando a declaração DOCTYPE é analisada. |
A assinatura da função de callback é function(e). Esta assinatura está presente no objeto Doctype. Para mais informações, consulte Doctype. |
|
comments |
Função de callback não assíncrona chamada quando o documento possui comentários. |
A assinatura da função de callback é function(e). Esta assinatura está presente no objeto Comments. Para mais informações, consulte Comments. |
|
text |
Função de callback não assíncrona chamada quando o documento possui nós de texto. |
A assinatura da função de callback é function(e). Esta assinatura está presente no objeto TextChunk. Para mais informações, consulte TextChunk. Nota
Este callback pode ser chamado várias vezes. O HTMLStream lê o texto em blocos e invoca esta função para cada bloco. Una todos os blocos para obter o texto completo. |
|
docend |
Função de callback não assíncrona chamada após a análise completa do documento. Use-a para anexar conteúdo, como informações de depuração em forma de comentários, ao final do documento HTML. |
A assinatura da função de callback é function(e). Esta assinatura está presente no objeto Docend. Para mais informações, consulte Docend. |
Tratamento de erros
O Edge Routine captura todas as exceções JavaScript lançadas pelas funções de callback. O HTMLStream interrompe o processamento e propaga a exceção para as camadas externas.
Se acionado pelo método reader.read em JavaScript, as exceções são relançadas.
Caso reader.read seja chamado enquanto o Edge Routine estiver em execução (por exemplo, retornando uma resposta a um cliente), o Edge Routine oculta as exceções e a resposta é interrompida. O cliente recebe apenas uma resposta parcial porque o HTMLStream trata os dados como fluxos que podem ser interrompidos antes que todos os dados sejam retornados. Esse comportamento é semelhante à forma como o TransformStream lida com exceções.
Parâmetros de callback
Cada função de callback recebe um objeto que representa as tags HTML selecionadas ou informações relacionadas. Este tópico descreve os tipos de parâmetros de callback: Element, TextChunk e Comments.
Use todos os parâmetros dentro das funções de callback. Invocar métodos ou atributos de um parâmetro fora de uma função de callback lança exceções JavaScript. Para usar dados de parâmetros fora de um callback, copie-os para outros objetos ou estruturas de dados JavaScript.
O parâmetro option nos métodos descritos abaixo é um objeto. Defina seu atributo HTML como true para conteúdo HTML ou false para conteúdo de texto. Quando definido como false, o HTMLStream chama a função
html encoding/escaping.
Element
-
Definição
Retornado quando a função de callback Element é chamada. Representa as tags HTML selecionadas.
-
Atributos
tagName(string): o nome da tag.attributes(iterator): retorna um iterador sobre todos os atributos no formato[name, value].removed(bool): indica se o elemento foi excluído. Somente leitura. Use remove() para excluir um elemento. Verifique este atributo para ignorar elementos já excluídos.namespaceURI: o URI do namespace do elemento (por exemplo, SVG ou Script). Somente leitura.
-
Métodos
-
Modificar atributos
getAttribute(name): obtém o valor de um atributo.
setAttribute(name, value): define ou modifica um atributo.
hasAttribute(name): verifica se um atributo existe.
removeAttribute(name): remove um atributo.
NotaTanto o nome quanto o valor do atributo devem ser strings.
-
Modificar conteúdo
before(data, option): insere conteúdo antes da tag do elemento.
after(data, option): insere conteúdo após a tag do elemento.
prepend(data, option): insere conteúdo após a tag de abertura. Exemplo:
<div>(prepend) |aaaa|(append)</div>.append(data, option): insere conteúdo antes da tag de fechamento. Exemplo:
<div>(prepend) |aaaa|(append)</div>.replace(data, option): substitui todo o elemento, incluindo tags e conteúdo aninhado.
setInnerContent(data, option): substitui o conteúdo do elemento preservando tags e atributos.
remove(): exclui o elemento. Define removed como true.
removeAndKeepContent(): remove tags e atributos, mas preserva o conteúdo.
-
TextChunk
-
Definição
Retornado quando a função de callback Text é chamada. Representa um bloco do texto HTML selecionado.
-
Atributos
removed(bool): indica se o elemento foi excluído. Somente leitura. Use remove() para excluir.text(string): o conteúdo de texto. Somente leitura. Pode ser um bloco parcial. Uma string vazia indica o último bloco — una todos os blocos para obter o texto completo.lastInTextNode(bool): indica se este é o último bloco. Somente leitura. Quando true, o atributo text retorna uma string vazia.
-
Métodos
Modificar conteúdo
before(data, option): insere conteúdo antes do elemento especificado (tag do elemento).
after(data, option): insere conteúdo após o elemento especificado (tag do elemento).
replace(data, option): substitui todo o elemento, incluindo as tags e tags aninhadas.
remove(): exclui o elemento especificado. Após a exclusão do elemento, o valor do atributo removed muda para true.
Comments
-
Definição
Retornado quando a função de callback Comments é chamada. Representa comentários no conteúdo HTML selecionado.
-
Atributos
removed(bool): indica se o elemento foi excluído. Somente leitura. Use remove() para excluir.text(string): o texto do comentário. Leitura e escrita — defina para sobrescrever comentários existentes.
-
Métodos
Modificar conteúdo
before(data, option): insere conteúdo antes do elemento especificado (tag do elemento).
after(data, option): insere conteúdo após o elemento especificado (tag do elemento).
replace(data, option): substitui todo o elemento, incluindo as tags e tags aninhadas.
remove(): exclui o elemento especificado. Após a exclusão do elemento, o valor do atributo removed muda para true.
Doctype
-
Definição
Retornado quando a função de callback DOCTYPE é chamada. Representa o DOCTYPE do conteúdo HTML.
-
Atributos
name(string): o nome do DOCTYPE. Somente leitura.publicId(string): o identificador público, ou null se não existir. Somente leitura.systemId(string): o identificador de sistema, ou null se não existir. Somente leitura.
Docend
-
Definição
Retornado quando a função de callback Docend é chamada. Representa o fim do documento HTML.
-
Métodos
append(string, option): anexa conteúdo ao final do documento HTML.