Saltar al contenido

Los protocolos internos

Cómo llega tu frontend a la webview sin servidor, qué esquemas registra el framework, y por qué el que sirve ficheros del disco es una decisión de seguridad y no una comodidad.

Los esquemas

Y una nota de plataforma: la forma exacta de cada esquema difiere entre sistemas —en Windows toman forma de dominio local por compatibilidad con su motor— pero el comportamiento es el mismo. Lo que cambia y sí importa es el origen resultante, que es lo del nivel 10.1.

El de recursos, y por qué tiene ámbito

Es el interesante. Sin él, mostrar una imagen que está en el disco del usuario exige leerla en Rust y mandarla por el puente —con el coste del nivel 15.3—. Con él, se pone la URL en la etiqueta y el motor la carga directamente.

JSON
{  "app": {    "security": {      "assetProtocol": {        "enable": true,        "scope": ["$APPDATA/imagenes/**", "$APPDATA/portadas/**"]      }    }  }}

Y tiene ámbito porque es una vía directa del disco a la webview que no pasa por ningún comando. Sin ámbito, cualquier código en tu frontend podría poner cualquier ruta en una etiqueta de imagen y leer el fichero. Con ámbito, solo lo declarado.

Dos detalles operativos:

  • El ámbito vive en la configuración, no en una capability. Es la excepción del nivel 27.3, y la razón es que no acota un comando sino el motor.
  • Y la política de contenido tiene que permitirlo. Habilitar el protocolo no basta: si tu img-src no incluye el esquema de recursos, el motor bloquea la carga igual. Es el fallo más común al activarlo.

Protocolo o puente

La decisión, que el nivel 15.3 anticipó:

La regla: si es un recurso que se muestra, el protocolo; si es un dato que se procesa o la decisión de servirlo tiene lógica, el puente.

Un esquema propio

La tercera opción, y resuelve el caso que las dos anteriores dejan fuera: servir contenido que generas, con lógica, sin pasarlo por el puente.

Rust
tauri::Builder::default()    .register_uri_scheme_protocol("miniatura", |ctx, request| {        // aquí hay lógica: comprobar, generar, cachear        let id = extraer_id(request.uri());        let bytes = generar_miniatura(id);   // o servirla de la caché        tauri::http::Response::builder()            .header("Content-Type", "image/webp")            .body(bytes)            .unwrap()    })
HTML
<img src="miniatura://proyecto-42" />

Con eso, la webview pide una miniatura por su identificador, el core decide qué sirve y comprueba lo que quiera, y los bytes no cruzan el puente. Es lo mejor de las dos columnas, y es la respuesta correcta para galerías, vistas previas y cualquier cosa que se muestre mucho.

Tres cosas que hay que tener en cuenta:

  • La política de contenido tiene que permitir tu esquema.
  • El manejador corre por cada petición, así que conviene que sea rápido o que cachee.
  • Y es una superficie: lo que ese manejador acepte en la URL es lo que la webview puede pedir. Aplica el criterio del nivel 14.4: un identificador de dominio, no una ruta.