La API HTMLStream permite procesar datos de streaming HTML en los puntos de presencia (POP), como datos bursátiles en tiempo real o registros de chat. Además, con la API HTMLStream puede transmitir datos de streaming HTML en fragmentos para acelerar la transmisión de datos.
Información de contexto
Edge Routine es ideal para una amplia variedad de escenarios de desarrollo frontend. Los datos especiales, como los encabezados User-Agent, las ubicaciones geográficas y las direcciones IP, se envían desde los POP. Por lo tanto, es posible que necesite modificar el flujo de una página HTML en tiempo real en los POP. Convencionalmente, se usan expresiones regulares para crear un analizador ad hoc que modifique el flujo de una página HTML. Sin embargo, este enfoque convencional puede provocar errores y no admite el procesamiento de flujos. Los analizadores de JavaScript de código abierto, como parse5 y htmlparser2, consumen una gran cantidad de recursos de memoria y degradan el rendimiento del sistema. Para resolver estos problemas, Edge Routine proporciona un analizador compatible con el procesamiento de flujos en los POP. Puede usar este analizador para modificar código y páginas HTML.
El analizador está integrado en Edge Routine y no se basa en estándares web.
Ejemplo
-
Escenario
Si necesita modificar todas las etiquetas de anclaje
<a/>de una página HTML para que apunten ahttp://www.taobao.com, utilice en Edge Routine el código que se muestra a continuación. -
Código de ejemplo
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álisis del resultado
El código de ejemplo anterior muestra cómo modificar un flujo HTML en tiempo real mediante la API HTMLStream. A continuación se describe el funcionamiento de HTMLStream:
La API Fetch recupera una expresión de flujo para la solicitud. Sin embargo, es posible que Edge Routine aún no haya recuperado el cuerpo de la respuesta de la capa de red. Como resultado, se reduce la frecuencia de la recolección de elementos no utilizados causada por el almacenamiento en búfer de datos.
-
HTMLStream también es un flujo compatible con la operación TransformStream. Después de que HTMLStream recibe un flujo, llama a la función de callback de reescritura para modificar la página HTML especificada en tiempo real. Si desea modificar una página HTML, debe obtener el flujo de datos sin procesar de la página HTML. A continuación, puede colocar el flujo de datos sin procesar en el flujo HTML que haya creado, como se describe en el paso 2 del código de ejemplo anterior.
El primer parámetro de HTMLStream es un flujo, que representa el flujo de datos sin procesar de la página HTML.
-
El segundo parámetro de HTMLStream es una matriz, que representa un grupo de reescritores. Un reescritor es una matriz que incluye un selector. El selector se usa para especificar el contenido HTML que desea modificar y seleccionar un objeto. Algunos atributos del objeto se llamarán como funciones de callback.
["a" , {....}]en el ejemplo anterior se usa para declarar un reescritor, que representa una matriz con dos elementos. La cadena "a" del ejemplo anterior representa el selector de elementos que se usa para localizar todas las etiquetas de anclaje del documento. El objeto del ejemplo anterior especifica el objeto de callback. Si decide usar un selector de elementos, el objeto puede contener las funciones de callback que se describen a continuación:La función de callback
element. La firma de esta función de callback es function(e). Esta función de callback se llama cuando se analizan los elementos seleccionados por el selector de elementos.La función de callback
comments. La firma de esta función de callback es function(e). Esta función de callback se llama cuando se analizan los comentarios que están anidados dentro de los elementos.La función de callback
text. La firma de esta función de callback es function(e). Esta función de callback se llama cuando se analiza el texto de los elementos. Esta función de callback puede llamarse varias veces. Debido al procesamiento de flujos, HTMLStream puede estar procesando un fragmento de una cadena.
Puede responder directamente a HTMLStream. Sin embargo, HTMLStream no almacena datos en búfer. A diferencia de parse5 y htmlparser2, HTMLStream no genera un árbol DOM, lo que reduce significativamente el tiempo de procesamiento y el consumo de memoria. De esta manera, HTMLStream puede ofrecer un throughput y una concurrencia altos al analizar contenido HTML.
Reescritor
El reescritor se usa para registrar el objeto que desea reescribir. El objeto es una matriz compuesta por dos elementos.
-
El primer elemento de la matriz debe ser de tipo cadena o null.
Cadena: especifica un selector de elementos que se usa para localizar un elemento o etiqueta.
-
null: especifica que el reescritor se aplica a un documento completo.
NotaEn la mayoría de los casos, no es necesario aplicar el reescritor a un documento completo. Si el reescritor se aplica a un documento completo, no puede localizar elementos.
-
El segundo elemento de la matriz debe ser un objeto de JavaScript. Este objeto se devuelve a la función de callback que haya registrado.
Si usa un selector de elementos, este objeto se denomina función de callback de elemento. Si usa un selector de documento, este objeto se denomina función de callback de documento.
Puede especificar uno o varios reescritores para una operación de HTMLStream. Puede especificar varios selectores de elementos, pero solo un selector de documento.
Sintaxis de los selectores de elementos
La sintaxis de los selectores de elementos es un subconjunto de la sintaxis de los selectores CSS. El lenguaje de programación de un selector de elementos puede ser distinto del lenguaje de programación de un selector CSS. A continuación se describe la sintaxis de los selectores de elementos:
*: especifica todos los elementos o etiquetas.div: especifica la etiqueta denominadadiv. Puede especificar otros nombres de etiqueta en este formato. Las etiquetas HTML y personalizadas son compatibles.E#id: especifica la etiqueta denominada E. El ID de la etiqueta se especifica medianteid.E.Class: especifica la etiqueta denominada E. La clase de la etiqueta se especifica medianteClass.E[attr]: especifica la etiqueta denominada E. Los atributos de la etiqueta incluyen el nombre attr.-
Atributos del elemento:
E[attr="a"]: especifica la etiqueta denominada E. Los atributos de la etiqueta incluyen attr, que está establecido en a. El valor distingue mayúsculas y minúsculas.E[attr^="a"]: especifica la etiqueta denominada E. Los atributos de la etiqueta incluyen attr, que está establecido en a. El valor no distingue mayúsculas y minúsculas.E[attr$="a"]: especifica la etiqueta denominada E. Los atributos de la etiqueta incluyen attr, cuyo valor termina con a.E[attr^="a"]: especifica la etiqueta denominada E. Los atributos de la etiqueta incluyen attr, cuyo valor comienza con a.E[attr*="a"]: especifica la etiqueta denominada E. Los atributos de la etiqueta incluyen attr, cuyo valor contiene a.E[attr|="a"]: especifica la etiqueta denominada E. Los atributos de la etiqueta incluyen attr, cuyo valor comienza con a- y se separa mediante comas (,). Por ejemplo: en-ch, en-us.
-
Orden entre elementos:
E F: especifica la etiqueta denominada F, que existe en el elemento primario denominado E.E > F: especifica la etiqueta denominada F cuyo elemento primario es la etiqueta denominada E.
E:not(S): especifica el elemento denominado E. S es otro selector de elementos. El elemento E solo se puede seleccionar cuando el selector se establece en false.
Funciones de callback para selectores de elementos
La tabla que se muestra a continuación describe las funciones de callback compatibles con los selectores de elementos.
Función de callback | Descripción | Firma de la función de callback |
element | Función de callback no asíncrona que se llama después de que los elementos seleccionados se analizan por completo. | La firma de la función de callback es function(e). Esta firma se incluye en el objeto Element. Para obtener más información, consulte Element. |
comments | Función de callback no asíncrona que se llama cuando los elementos seleccionados tienen comentarios. | La firma de la función de callback es function(e). Esta firma se incluye en el objeto Comments. Para obtener más información, consulte Comments. |
text | Función de callback no asíncrona que se llama cuando se analiza el texto devuelto a la función de callback. | La firma de la función de callback es function(e). Esta firma se incluye en el objeto TextChunk. Para obtener más información, consulte TextChunk. Nota Esta función de callback puede llamarse varias veces. Cuando HTMLStream lee fragmentos de texto de los datos HTML sin procesar, esta función de callback se llama cada vez que se analiza un fragmento. Si desea consultar el texto completo, debe cargar y combinar todos los fragmentos de texto. |
Un selector de elementos puede omitir todas las funciones de callback anteriores. En este caso, los elementos relevantes se imprimen directamente sin procesarse. Si desea modificar un fragmento específico del texto, solo necesita registrar la función de callback obligatoria.
Selector de documento
Un selector de documento se usa para seleccionar un documento especificado. Para usar un selector de documento, establezca el primer elemento de la matriz del reescritor en null. En la operación de HTMLStream, solo se puede configurar un selector de documento.
Funciones de callback para selectores de documento
Las funciones de callback para selectores de documento son similares a las funciones de callback para selectores de elementos. La tabla que se muestra a continuación describe las funciones de callback compatibles con los selectores de documento.
Función de callback | Descripción | Firma de la función de callback |
doctype | Función de callback no asíncrona que se llama cuando se analiza la declaración de tipo de documento (DOCTYPE) del documento especificado. | La firma de la función de callback es function(e). Esta firma se incluye en el objeto Doctype. Para obtener más información, consulte Doctype. |
comments | Función de callback no asíncrona que se llama cuando el documento especificado tiene comentarios. | La firma de la función de callback es function(e). Esta firma se incluye en el objeto Comments. Para obtener más información, consulte Comments. |
text | Función de callback no asíncrona que se llama cuando el documento especificado tiene nodos de texto. | La firma de la función de callback es function(e). Esta firma se incluye en el objeto TextChunk. Para obtener más información, consulte TextChunk. Nota Esta función de callback puede llamarse varias veces. Cuando HTMLStream lee fragmentos de texto de los datos HTML sin procesar, esta función de callback se llama cada vez que se analiza un fragmento. Si desea consultar el texto completo, debe cargar y combinar todos los fragmentos de texto. |
docend | Función de callback no asíncrona que se llama después de que el documento especificado se analiza por completo. Esta función de callback agrega contenido, como información de depuración, al final del documento HTML como comentarios. Puede usar esta información para solucionar problemas. | La firma de la función de callback es function(e). Esta firma se incluye en el objeto Docend. Para obtener más información, consulte Docend. |
Manejo de errores
Edge Routine captura todas las excepciones de JavaScript que lanzan las funciones de callback anteriores. Mientras tanto, HTMLStream deja de procesar los flujos HTML y propaga la excepción a las capas externas.
Si el método reader.read se desencadena en JavaScript, las excepciones se vuelven a lanzar.
Si el método reader.read se llama en HTMLStream mientras Edge Routine está en ejecución, Edge Routine oculta las excepciones. Por ejemplo, si las excepciones se producen cuando Edge Routine devuelve una respuesta a un cliente, la respuesta se interrumpe y el cliente solo recibe una parte de la respuesta. Esto se debe a que HTMLStream trata los datos como flujos. En este caso, el flujo puede interrumpirse antes de que todos los datos se devuelvan al cliente. El método que usa HTMLStream para procesar excepciones es similar al método que usa TransformStream. TransformStream también escribe y lee datos como flujos.
Parámetros de callback
Cada función de callback recibe un objeto que representa las etiquetas HTML seleccionadas u otra información relevante. Este objeto también se conoce como parámetro de callback. Este tema describe los parámetros de callback como Element, TextChunk y Comments.
Todos los parámetros deben pasarse a las funciones de callback. Si los métodos o atributos de un parámetro se invocan fuera de una función de callback, se lanzan excepciones de JavaScript. Para evitar este problema, puede pasar los parámetros deseados a otros objetos o estructuras de datos de JavaScript.
La opción de los métodos que se describen en este tema representa un objeto. Puede establecer el atributo HTML del objeto en true o false. El valor true especifica contenido HTML y false especifica contenido de texto. Si establece el atributo HTML en false, HTMLStream llama a la función
html encoding/escaping.
Element
-
Definición
Este objeto se devuelve cuando se llama a la función de callback de Element. Este objeto representa las etiquetas HTML seleccionadas.
-
Atributos
tagName(string): especifica el nombre de la etiqueta.attributes(iterator): devuelve un iterador que localiza todos los atributos que se especifican en el formato[name, value].removed(bool): especifica si se elimina el elemento. Este atributo es de solo lectura. Puede llamar al método remove() para eliminar un elemento. Por lo general, debe configurar este atributo para omitir los elementos que ya están eliminados.namespaceURI: la URI de namespace de un elemento, como el elemento SVG o Script. Este atributo es de solo lectura.
-
Métodos
-
Modificar atributos
getAttribute(name): consulta el nombre de un atributo de un elemento especificado.
setAttribute(name, value): establece un nombre de atributo para un elemento especificado y modifica el nombre de atributo de un elemento especificado.
hasAttribute(name): consulta si existe un nombre de atributo en un elemento especificado.
removeAttribute(name): elimina un nombre de atributo de un elemento especificado.
NotaTanto el nombre del atributo como el valor deben ser de tipo cadena.
-
Modificar contenido
before(data, option): inserta contenido antes del elemento especificado (la etiqueta del elemento).
after(data, option): inserta contenido después del elemento especificado (la etiqueta del elemento).
prepend(data, option): inserta contenido antes del contenido del elemento especificado (después de la etiqueta de apertura). Ejemplo:
<div>(prepend) |aaaa|(append)</div>.append(data, option): inserta contenido después del contenido del elemento especificado (antes de la etiqueta de cierre). Ejemplo:
<div>(prepend) |aaaa|(append)</div>.replace(data, option): reemplaza el elemento completo, incluidas las etiquetas y las etiquetas anidadas.
setInnerContent(data, option): especifica el contenido del elemento y conserva las etiquetas y los atributos.
remove(): elimina el elemento especificado. Después de eliminar el elemento, el valor del atributo removed cambia a true.
removeAndKeepContent(): elimina las etiquetas y los atributos del elemento especificado y conserva el contenido.
-
TextChunk
-
Definición
Este objeto se devuelve cuando se llama a la función de callback de Text. Este objeto representa un fragmento del texto HTML seleccionado.
-
Atributos
removed(bool): especifica si se elimina el elemento. Este atributo es de solo lectura. Puede llamar al método remove() para eliminar un elemento. Por lo general, debe configurar este atributo para omitir los elementos que ya están eliminados.text(string): especifica el contenido de texto. Este atributo es de solo lectura. El texto puede ser un fragmento de texto. Si la cadena está vacía, indica que se devuelve el último fragmento de texto. En este caso, puede combinar todos los fragmentos de texto.lastInTextNode(bool): especifica si es el último fragmento de texto. Este atributo es de solo lectura. Si el valor de este atributo es true, el atributo text devuelve una cadena vacía.
-
Métodos
Modificar contenido
before(data, option): inserta contenido antes del elemento especificado (la etiqueta del elemento).
after(data, option): inserta contenido después del elemento especificado (la etiqueta del elemento).
replace(data, option): reemplaza el elemento completo, incluidas las etiquetas y las etiquetas anidadas.
remove(): elimina el elemento especificado. Después de eliminar el elemento, el valor del atributo removed cambia a true.
Comments
-
Definición
Este objeto se devuelve cuando se llama a la función de callback de Comments. Este objeto representa los comentarios del contenido HTML seleccionado.
-
Atributos
removed(bool): especifica si se elimina el elemento. Este atributo es de solo lectura. Puede llamar al método remove() para eliminar un elemento. Por lo general, debe configurar este atributo para omitir los elementos que ya están eliminados.text(string): especifica los comentarios existentes o los comentarios para sobrescribir los existentes. Este atributo es de lectura y escritura.
-
Métodos
Modificar contenido
before(data, option): inserta contenido antes del elemento especificado (la etiqueta del elemento).
after(data, option): inserta contenido después del elemento especificado (la etiqueta del elemento).
replace(data, option): reemplaza el elemento completo, incluidas las etiquetas y las etiquetas anidadas.
remove(): elimina el elemento especificado. Después de eliminar el elemento, el valor del atributo removed cambia a true.
Doctype
-
Definición
Este objeto se devuelve cuando se llama a la función de callback de DOCTYPE. Este objeto representa el DOCTYPE del contenido HTML seleccionado.
-
Atributos
name(string): especifica el nombre de DOCTYPE. Este atributo es de solo lectura.publicId(string): devuelve un identificador público. Si no existe ningún identificador público, se devuelve un valor de null. Este atributo es de solo lectura.systemId(string): devuelve un identificador de sistema. Si no existe ningún identificador de sistema, se devuelve un valor de null. Este atributo es de solo lectura.
Docend
-
Definición
Este objeto se devuelve cuando se llama a la función de callback de Docend. Este objeto representa el final de un documento HTML.
-
Métodos
append(string, option): agrega contenido al final del documento HTML.