Clipboard API: respeta la intención del usuario
Diseña escrituras, lecturas, permisos, alternativas y controles de privacidad del Clipboard API alrededor de una acción explícita.
BotBrowser Team
Quieres la documentación estructurada de Plataforma?
Este artículo forma parte de la biblioteca editorial. Para pasos de configuración, material de referencia y actualizaciones continuas, entra en la sección de docs.
El Clipboard API permite que una página autorizada escriba o lea datos del portapapeles del sistema, pero el resultado no demuestra que una persona quisiera revelar ese contenido. BotBrowser puede repetir una página propia con un perfil declarado y registrar los estados visibles de permiso, alternativa y estado; no puede leer el portapapeles real de una persona, conceder permisos ni decidir si el contenido se compartió deliberadamente. Un diseño seguro empieza por la tarea solicitada y pide la operación mínima que la completa.
La especificación Clipboard API del W3C separa las operaciones asíncronas de las reglas de permiso y activación del usuario. La referencia Clipboard API de MDN describe la superficie del navegador, y la guía Clipboard asíncrono de web.dev muestra patrones de mejora progresiva. Juntas sostienen un límite importante: una promesa resuelta indica lo que aceptó el navegador, no lo que una persona pegó, revisó o autorizó en un servicio remoto.
Resumen
- Empieza con una acción visible y declara si la página escribirá, leerá o transformará datos del portapapeles.
- Trata
navigator.clipboard.writeText()ynavigator.clipboard.readText()como decisiones de privacidad distintas, con alternativas separadas. - Mantén un campo seleccionable, un recorrido de teclado y un mensaje de estado cuando el contexto seguro, el foco, la política o el permiso bloqueen la API.
- Registra un estado redactado como
write-successoread-denied, nunca el contenido del portapapeles. - Usa una prueba sintética para comparar soporte y fallos; BotBrowser no puede fabricar un portapapeles real ni una decisión de permiso.
Contenido
- Define la acción y la intención
- Separa las rutas de escritura y lectura
- Gestiona texto y formatos enriquecidos
- Mantén visible la alternativa y el foco
- Registra resultados sin recopilar secretos
- Verifica con una prueba acotada
- Conclusión práctica
Define La Acción Y La Intención
El trabajo con el portapapeles comienza con una tarea concreta, no con una consulta en segundo plano. “Copiar este número de factura” es una escritura con un valor visible. “Pegar un código en este formulario” es una lectura que debe comenzar después de elegir el destino. “Importar contenido con formato” puede requerir ClipboardItem y una lista permitida de formatos. Escribe la tarea en la etiqueta del control y en el estado antes de invocar navigator.clipboard, para que la persona pueda anticipar el resultado.
El contexto del navegador importa. El modelo del W3C y la guía de MDN describen requisitos de contexto seguro y comprobaciones que pueden variar según origen, foco, incrustación, política y activación transitoria. Cargar una página no es intención del usuario. No llames a readText() desde un temporizador, un iframe oculto, una devolución de analítica o una precarga de ruta solo porque quizá se necesite el valor. Un resultado denegado o vacío no prueba que la persona no tenga contenido en el portapapeles.
Usa vocabulario común para la interfaz y el registro: idle, intent-recorded, write-requested, read-requested, completed, denied, cancelled, unsupported y failed. completed debe significar que la página recibió el resultado del navegador y actualizó un control visible. No significa que el sistema operativo mostrara una notificación, que otra aplicación aceptara el pegado ni que un servidor guardara el valor.
La guía de permisos del navegador explica por qué el estado de un permiso puede ser observable sin convertirse en una afirmación de identidad. Aplica el mismo límite aquí: el estado del portapapeles sirve para la interacción actual, no para un perfil permanente. Ata la operación a un identificador como clip-17 y hazlo expirar al cambiar de tarea o ruta.
Separa Las Rutas De Escritura Y Lectura
Escribir un valor elegido por la página suele exponer menos que leer cualquier contenido del portapapeles. Da a la escritura una etiqueta descriptiva como “Copiar código de recuperación” y muestra el valor de origen. La aplicación puede llamar a navigator.clipboard.writeText(value) tras el clic y anunciar write-success o write-denied. Si la promesa es rechazada, conserva el valor en un campo seleccionable en lugar de afirmar que se copió.
Leer es otra decisión. Pide que la persona enfoque el campo destino, explica que la página leerá el portapapeles y llama a navigator.clipboard.readText() solo desde esa acción deliberada. Evita una lectura silenciosa seguida de una búsqueda de cuenta o de clasificación de sugerencias. El contenido puede ser una contraseña, un mensaje privado o un dato de pago. Consume el resultado una vez, valida el formato del campo y elimina el valor del estado temporal.
La detección de características separa una API ausente de una solicitud rechazada, pero no predice el permiso. Comprueba globalThis.isSecureContext y navigator.clipboard?.writeText o readText antes de mostrar la ruta preferida. Esta tabla mantiene separada la observación del navegador y la decisión del producto.
| Observación del navegador | Estado del producto | Acción visible |
|---|---|---|
| Falta el método de la API | unsupported | Mantén visible el campo seleccionable o la ruta de pegado por teclado. |
La promesa rechaza con NotAllowedError | denied | Explica que el navegador no permitió la operación y conserva la alternativa. |
| La persona cierra o abandona el flujo | cancelled | Devuelve el foco al control original sin reintentar automáticamente. |
| La promesa se resuelve después de escribir | completed | Anuncia que la página entregó el valor elegido al navegador. |
| La lectura no supera la validación | failed | Conserva el campo y muestra el formato requerido. |
La guía de límites de permisos de Web Share cubre otra capacidad iniciada por el usuario. La lección es la misma: una alternativa pertenece al contrato normal, no es un intento oculto de saltar la política. Mantén la opción de copiar o pegar visible desde el primer render.
Gestiona Texto Y Formatos Enriquecidos
Los flujos de solo texto son más fáciles de explicar porque pueden fijar una política de longitud y caracteres antes de escribir. Recorta solo si la tarea declara que los espacios no importan; de lo contrario conserva el texto seleccionado. Para un código, valida una forma como AB-1234 después de leer y rechaza líneas adicionales sin registrar el contenido. Una validación correcta solo significa que el valor encaja en este campo, no que sea auténtico.
Las operaciones enriquecidas necesitan un contrato más estrecho. ClipboardItem puede exponer text/plain y text/html, y la aplicación debe pedir o escribir solo los tipos necesarios. Sanitiza HTML antes de insertarlo; la representación del navegador no es marcado confiable. Mantén un máximo explícito como 256 KiB en la prueba y rechaza tipos MIME inesperados antes de analizar. La especificación define la interfaz, pero no hace seguro el HTML de la aplicación.
No conviertas silenciosamente una lectura enriquecida en una importación de texto arbitraria. Indica qué representación usarás, muestra una vista previa cuando el contenido sea complejo y permite deshacer o borrar. Si falta text/html, ofrece text/plain y comunica la pérdida de formato. Si aparece una imagen, conserva límites de decodificación y almacenamiento en el contrato de la aplicación.
Para escribir, fija la representación de texto plano cuando sea una alternativa válida. Un botón que solo escribe HTML puede dejar sin resultado a un usuario de teclado o a un flujo de terminal. Una prueba sencilla expresa la superficie prevista:
const value = selectedValue;
const result = { operation: 'write', fixtureId: 'clip-17', state: 'requested' };
if (!globalThis.isSecureContext || !navigator.clipboard?.writeText) {
result.state = 'unsupported';
} else {
try {
await navigator.clipboard.writeText(value);
result.state = 'write-success';
} catch (error) {
result.state = error?.name === 'NotAllowedError' ? 'write-denied' : 'write-failed';
}
}
El registro excluye deliberadamente value. Una prueba puede afirmar el estado visible usando datos sintéticos clip-17 sin conservar el contenido. Mantén idénticos los nombres MIME, los límites y los identificadores al traducir esta prueba.
Mantén Visible La Alternativa Y El Foco
La mejora progresiva debe dejar utilizable la tarea cuando el Clipboard API falte o sea rechazado. Una copia puede seleccionar un <input readonly> y mostrar una instrucción para el teclado. Un pegado puede dejar el campo editable para usar el atajo del sistema. Una importación enriquecida puede aceptar un archivo o texto plano. Estas rutas deben estar disponibles sin abrir de nuevo el aviso de permiso.
La retroalimentación de estado es parte de la corrección. Anuncia write-success, read-denied o unsupported en una región viva, mueve el foco al control siguiente después del éxito y devuélvelo al control de origen si falla. No deshabilites el único campo durante la promesa. Un reintento debe exigir un clic nuevo y no reutilizar un valor obsoleto después de una navegación.
Los recorridos de teclado y tecnologías de asistencia necesitan el mismo límite de intención. La activación de un botón etiquetado es una acción; un efecto al cargar no lo es. Usa un nombre accesible específico, evita “Continuar” para una operación del portapapeles y explica si el resultado se copió, insertó o quedó disponible para selección manual. Prueba zoom, alto contraste, lectores de pantalla y etiquetas largas localizadas.
La incrustación cambia la alternativa. Un frame de otro origen puede encontrar una Permissions Policy o un límite de foco aunque la página superior sea segura. El frame debe indicar qué propietario puede resolverlo y ofrecer un handoff de primera parte solo si la aplicación ya lo tiene. Nunca pongas el texto del portapapeles en una cadena de consulta para moverlo entre frames.
Registra Resultados Sin Recopilar Secretos
La telemetría debe responder “¿qué rama tomó el producto?” y no “¿qué había en el portapapeles?”. Una lista permitida puede contener fixtureId, operation, state, mimeType, browserVersion, context y fallback. Debe excluir texto, HTML, bytes de imagen, identificadores de cuenta y URL completas. Una fila read-denied ayuda al soporte; una contraseña copiada no.
Separa la propiedad del navegador y de la aplicación. El navegador decide si expone la solicitud y puede rechazarla. La página valida y muestra el resultado. Un servidor puede confirmar un valor enviado, pero esa confirmación no demuestra que el navegador leyera o escribiera el portapapeles. Registra las etapas separadas para que una respuesta tardía no sobrescriba un intento nuevo como clip-17.
El estado del permiso no es una huella segura. Versión, perfil, foco, política, acción del usuario e integración del sistema pueden cambiar el resultado. No combines disponibilidad del portapapeles con fuentes, dispositivos u otros permisos para crear una puntuación de riesgo. La guía de contextos seguros establece la regla general: una comprobación debe servir a una función declarada, no identificar a una persona.
Conserva los datos poco tiempo y con propósito explícito. Guarda la prueba sintética solo durante la comparación de una versión y después agrega el estado o elimínalo conforme a la política. Para soporte pide el identificador redactado mínimo. Nunca pidas una captura con contenido privado, un perfil completo ni un evento sin redactar.
Verifica Con Una Prueba Acotada
Usa una página propia y un valor sintético para recorrer toda la matriz. Empieza con clip-17, un botón de copia visible, un campo de pegado editable y una región status. Ejecuta la prueba en contexto seguro y repítela quitando el método, rechazando la promesa y eligiendo la alternativa. Conserva browserVersion, viewport, origin y fixtureRevision junto al resultado. La comparación pregunta qué campo declarado cambió, no qué harán todos los sistemas.
La guía Clipboard asíncrono de web.dev ayuda con la mejora progresiva, mientras que W3C y MDN definen semántica y superficie. Revisa las tres fuentes antes de cambiar el lenguaje de soporte. No uses un anuncio antiguo de Chrome ni una URL de Chrome rota como evidencia; el conjunto público de este tema es la especificación W3C, la referencia MDN y la guía web.dev.
Una fila de auditoría puede ser compacta:
{
"fixtureId": "clip-17",
"operation": "write",
"state": "write-success",
"fallback": "none",
"mimeType": "text/plain",
"browserVersion": "156.0",
"viewport": "1280x800"
}
La fila registra un resultado del navegador, no una prueba de que alguien pegó el valor. Si la primera diferencia es unsupported, revisa el contexto seguro y la detección. Si es write-denied, revisa activación, foco, política y decisión. Si el estado visible es incorrecto aunque la promesa se resuelva, revisa la máquina de estados y la región viva.
BotBrowser puede repetir este viaje sintético declarado en un contexto controlado y conservar los datos de perfil y viewport usados para comparar. No puede leer el portapapeles real, fabricar un pegado del sistema, conceder un aviso de permiso ni certificar que otra aplicación aceptó el valor. Mantén la decisión final limitada a la prueba, versión, origen y resultado visibles observados.
Fuentes Públicas
- Clipboard API, W3C
- Clipboard API, MDN
- Async Clipboard, web.dev
- Consistencia de automatización de BotBrowser
Conclusión Práctica
Pide una acción visible, separa las decisiones de escritura y lectura, valida formatos antes de usarlos y deja una alternativa seleccionable en pantalla. Registra solo el estado de la operación y el contexto declarado; nunca conviertas el contenido o el permiso en una señal de identidad. BotBrowser puede repetir un flujo sintético autorizado, pero navegador, persona, página y servidor conservan sus propios límites.
Este artículo forma parte de la guía: Superficies de la plataforma web: mapa de revisión
Artículos Relacionados
Datos de compatibilidad de APIs y alternativas del navegador
PlataformaWeb Share API: límites de permisos y respaldos seguros
PlataformaIdle Detection API: control, permisos y privacidad
PlataformaDe los estándares del navegador al estado de implementación
PlataformaEl soporte de una función no es su calidad
PlataformaWeb Share API y uso compartido iniciado por la persona
Lleva BotBrowser de la investigación a producción
Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.