# Servir archivos a navegadores web

🤖/file/serve sirve archivos a navegadores web.

![Robot /file/serve](/assets/images/robots/240x240/file-serve.png)

Cuando quieras que Transloadit transforme archivos al vuelo, puedes usar este Robot para determinar qué Step de un Template debe entregarse al usuario final (mediante una CDN), así como para agregar información adicional a los archivos entregados, como encabezados. De esta manera, por ejemplo, puedes indicarle a la CDN durante cuánto tiempo debe conservar copias en caché del resultado. De forma predeterminada, indicamos a los navegadores que almacenen el resultado en caché durante 72h (`259200` segundos) y a las CDN que almacenen el contenido en caché durante 24h (`86400` segundos). Usa el parámetro `cache_duration` para personalizar ambos valores a la vez.

🤖/file/serve actúa únicamente como capa de enlace entre nuestro motor de Assembly y la entrega de archivos mediante HTTP. Te permite seleccionar, mediante el parámetro `use`, el resultado adecuado de una serie de Steps y configurar encabezados en el contenido original. Ahí terminan sus responsabilidades. A continuación, 🤖/tlcdn/deliver se encarga de distribuir globalmente este contenido original y de garantizar que se almacene en caché cerca de tus usuarios finales cuando hagan solicitudes como [https://my-app.tlcdn.com/resize-img/canoe.jpg?w=500⁠](https://my-app.tlcdn.com/resize-img/canoe.jpg?w=500), entre otras. 🤖/tlcdn/deliver no forma parte de tus Assembly Instructions, pero puede aparecer en tus facturas, ya que la distribución de las copias en caché genera cargos por ancho de banda. 🤖/file/serve solo genera cargos cuando la CDN no tiene una copia en caché y solicita que se vuelva a generar el contenido original, lo cual, según tu configuración de caché, podría suceder apenas una vez al mes o al año por cada archivo o transformación.

Aunque en teoría podrías usar [🤖/file/serve](/es/docs/robots/file-serve.md) directamente en archivos HTML, recomendamos firmemente no hacerlo. Si tu sitio se vuelve popular y la URL del contenido multimedia que gestiona /file/serve recibe un millón de solicitudes, se realizarán un millón de nuevos cambios de tamaño de imagen. Colocarlo detrás de una CDN (y aprovechar el almacenamiento en caché que esta proporciona) garantiza que tanto los cargos de encoding como las latencias se mantengan bajos.

Considera también configurar encabezados de caché y directivas de control de caché para controlar cómo se almacena en caché y se invalida el contenido en los servidores perimetrales de la CDN, equilibrando la actualización del contenido y la eficiencia.

## Seguridad de Smart CDN con URL firmadas

Puedes aprovechar las [URL firmadas de Smart CDN](/es/docs/api/authentication.md#smart-cdn) para evitar el uso indebido de nuestra plataforma de encoding. A continuación se muestra un ejemplo rápido de Node.js que usa nuestro SDK de Node, y también hay [ejemplos para otros lenguajes y SDK](/es/docs/api/authentication.md#example-code).

```javascript
// yarn add transloadit
// or
// npm install --save transloadit

import { Transloadit } from 'transloadit'

const transloadit = new Transloadit({
  authKey: 'YOUR_TRANSLOADIT_KEY',
  authSecret: 'YOUR_TRANSLOADIT_SECRET',
})

const url = transloadit.getSignedSmartCDNUrl({
  workspace: 'YOUR_WORKSPACE',
  template: 'YOUR_TEMPLATE',
  input: 'image.png',
  urlParams: { height: 100, width: 100 },
})

console.log(url)

```

Esto generará una URL firmada de Smart CDN que incluye parámetros de autenticación, lo que impide el acceso no autorizado a tus endpoints de transformación.

Para integraciones nuevas, usa el formato moderno `sig` + `exp`. Las firmas heredadas `s` están obsoletas. Ten en cuenta también que el periodo de vencimiento funciona en la práctica como periodo de caché para los resultados firmados: los vencimientos más cortos refuerzan el control de acceso, mientras que los más largos mejoran la reutilización de la caché y reducen el volumen de encoding.

## Más información

* [Entrega de contenido](/es/services/content-delivery.md)
* Precios de [🤖/file/serve](/es/docs/robots/file-serve.md)
* Precios de [🤖/tlcdn/deliver](/es/docs/robots/tlcdn-deliver.md)
* Publicación del blog sobre la [función de vista previa de archivos EN (English)](/blog/2024/06/file-preview-with-smart-cdn.md)

<span aria-hidden="true" id="usage-example"></span>

## Ejemplo de uso

Entrega archivos transformados con una duración explícita de la caché del navegador y de la CDN:

```
{
  "steps": {
    "resized": {
      "robot": "/image/resize",
      "use": ":original",
      "width": 800,
      "height": 450,
      "resize_strategy": "fit"
    },
    "served": {
      "robot": "/file/serve",
      "use": "resized",
      "cache_duration": 86400
    }
  }
}
```

<span aria-hidden="true" id="parameters"></span>

## Parámetros

* <span aria-hidden="true" id="interpolate"></span>

### `interpolate`

`boolean | Record<string, boolean>`\
Controla si las Assembly Variables se interpolan en campos de instrucciones individuales.\
De forma predeterminada, la mayoría de los campos de instrucciones de los Robots interpolan Assembly Variables. Establece esta opción en `false` para tratar todos los campos de instrucciones como texto literal, o establece la ruta de un campo individual en `false` para tratar únicamente ese campo como texto literal. En el caso de los campos específicos de un Robot que son literales de forma predeterminada, establece esta opción en `true` o la ruta de ese campo en `true` para volver a habilitar la interpolación.\
Usa nombres de campos como `path` o rutas con puntos como `ffmpeg.vf` para los objetos anidados.

* <span aria-hidden="true" id="output_meta"></span>

### `output_meta`

`Record<string, boolean> | boolean | Array<string>`\
Te permite especificar un conjunto de metadatos cuyo cálculo requiere más recursos de CPU y que, por lo tanto, está desactivado de forma predeterminada para que tus Assemblies se procesen rápidamente.\
Para imágenes, puedes añadir `"has_transparency": true` a este objeto para determinar si la imagen contiene partes transparentes y `"dominant_colors": true` para extraer un array de códigos de color hexadecimales de la imagen.\
Para imágenes, también puedes añadir `"blurhash": true` para extraer una cadena [BlurHash⁠](https://blurha.sh), una representación compacta de un marcador de posición para la imagen que resulta útil para mostrar una vista previa desenfocada mientras se carga la imagen completa.\
Para videos, puedes añadir el parámetro `"colorspace": true` para extraer el espacio de color del video de salida.\
Para videos, también puedes añadir `"interlaced": true` para detectar si el video está entrelazado. Esto combina el indicador `field_order` de ffprobe, cuyo costo en recursos de procesamiento es bajo, con una pasada de muestreo limitada mediante `idet` sobre los primeros fotogramas de la fuente, y expone `interlaced`, `field_order` y un objeto de diagnóstico `interlace_detection` en `file.meta`. Esto requiere muchos recursos computacionales y se factura en consecuencia.\
Para audio, puedes añadir `"mean_volume": true` para obtener un único valor que represente el volumen promedio del archivo de audio.\
También puedes establecerlo en `false` para omitir la extracción de metadatos y acelerar la transcodificación.

* <span aria-hidden="true" id="user_meta"></span>

### `user_meta`

`Record<string, any>`(valor predeterminado: `{}`)\
Añade metadatos personalizados a cada archivo emitido por este Robot sin modificar el contenido del archivo.\
Los valores se combinan con los `user_meta` existentes en el archivo de entrada. Si ambos objetos contienen la misma clave, el valor de este Robot tiene prioridad. Se admiten Assembly Variables, por ejemplo `{ "internal_file_id": "${file.id}" }`.

* <span aria-hidden="true" id="result"></span>

### `result`

`boolean`(valor predeterminado: `false`)\
Indica si los resultados de este Step deben aparecer en el Assembly Status JSON

* <span aria-hidden="true" id="queue"></span>

### `queue`

`batch`\
Establecer la cola en «batch» reduce manualmente la prioridad de los Jobs de este Step para evitar consumir cupos prioritarios con Jobs que no necesitan un tiempo de espera cero en la cola

* <span aria-hidden="true" id="force_accept"></span>

### `force_accept`

`boolean`(valor predeterminado: `false`)\
Forzar a un Robot a aceptar un tipo de archivo que habría ignorado.\
De forma predeterminada, los Robots ignoran los archivos que no reconocen.[🤖/video/encode](/es/docs/robots/video-encode.md), por ejemplo, ignorará sin problemas las imágenes de entrada.\
Si configuras el parámetro `force_accept` como `true`, puedes forzar a los Robots a aceptar todos los archivos que reciban. Esto normalmente provocará errores y solo debe usarse para depuración o para abordar casos extremos.

* <span aria-hidden="true" id="ignore_errors"></span>

### `ignore_errors`

`boolean | Array<meta | execute>`(valor predeterminado: `[]`)\
Ignorar errores durante fases específicas del procesamiento.\
Establecer este parámetro en `["meta"]` hará que el Robot ignore los errores durante la extracción de metadatos.\
Establecer este parámetro en `["execute"]` hará que el Robot ignore los errores durante la fase principal de ejecución.\
Configurar este parámetro como `true` equivale a `["meta", "execute"]` y hará que se ignoren los errores en ambas fases.

* <span aria-hidden="true" id="use"></span>

### `use`

`string | Array<string> | Array<object> | object`\
Especifica qué Step o Steps se usarán como entrada.

* Puedes elegir cualquier nombre para los Steps, excepto `":original"` (reservado para las subidas de usuarios gestionadas por Transloadit)
* Puedes proporcionar varios Steps como entrada mediante arrays:

```json
{  
  "use": [  
    ":original",  
    "encoded",  
    "resized"  
  ]  
}  
```

* También puedes etiquetar los Steps de entrada con `as` para comunicar la intención semántica a los Robots:

```json
{  
  "use": [  
    {  
      "name": ":original",  
      "as": "image"  
    },  
    {  
      "name": ":original",  
      "as": "mask"  
    }  
  ]  
}  
```

**Consejo**\
Probablemente eso sea todo lo que necesitas saber sobre `use`, pero puedes consultar los [casos de uso avanzados](/es/docs/topics/use-parameter.md).

* <span aria-hidden="true" id="cache_duration"></span>

### `cache_duration`

`string | number`\
Una duración opcional, en segundos, durante la cual el archivo servido debe almacenarse en caché. Cuando se establece, este valor se usa tanto para la directiva `max-age` (caché del navegador) como para la directiva `s-maxage` (caché compartida o de CDN) en el encabezado `Cache-Control`, lo que anula los valores predeterminados. Por ejemplo, establecer `cache_duration` en `43200` almacenaría el archivo en caché durante 12 horas.\
Esto es útil para controlar la retención de datos en las CDN. Por ejemplo, si tus archivos temporales se eliminan después de 24 horas, puedes establecer `cache_duration` en `86400` para garantizar que las copias almacenadas en caché también caduquen dentro de ese plazo.

* <span aria-hidden="true" id="headers"></span>

### `headers`

`Record<string, string>`(valor predeterminado: `{"Access-Control-Allow-Headers":"X-Requested-With, Content-Type, Cache-Control, Accept, Content-Length, Transloadit-Client, Authorization, Range, If-Range","Access-Control-Allow-Methods":"POST, GET, PUT, DELETE, OPTIONS","Access-Control-Allow-Origin":"*","Access-Control-Expose-Headers":"Transloadit-Assembly-URL, Content-Range, Content-Length, Accept-Ranges","Cache-Control":"public, max-age=259200, s-maxage=86400","Content-Type":"${file.mime}; charset=utf-8","Transloadit-Assembly":"…","Transloadit-RequestID":"…","Accept-Ranges":"bytes"}`)\
Un objeto que contiene una lista de encabezados que se establecerán para un archivo cuando lo entreguemos a una CDN o un navegador web, como `{ FileURL: "${file.url_name}" }`. Estos encabezados se combinarán con los valores predeterminados y pueden incluir cualquier [Assembly Variable](/es/docs/topics/assembly-instructions.md#assembly-variables) disponible.\
El encabezado `Accept-Ranges: bytes` indica que se admiten solicitudes de rango HTTP para desplazarse por la línea de tiempo durante la reproducción de contenido multimedia. Esto depende de que todos los backends de almacenamiento de Transloadit (S3, GCS, etc.) respeten los encabezados de solicitud Range. Los encabezados CORS incluyen `Range` y `If-Range` en `Access-Control-Allow-Headers` para permitir solicitudes de rango entre orígenes, y exponen `Content-Range`, `Content-Length` y `Accept-Ranges` mediante `Access-Control-Expose-Headers` para que el código JavaScript del navegador pueda leer estos valores.

<span aria-hidden="true" id="related-blog-posts"></span>

## Publicaciones relacionadas del blog

* [Building an alt-text to speech generator with Transloadit EN (English)](/blog/2022/05/image-tts.md) 9 de mayo de 2022
* [Easy instant website screenshots via Transloadit CDN EN (English)](/blog/2022/05/website-preview.md) 11 de mayo de 2022
* [Smart CDN enhanced with AI-powered face detection EN (English)](/blog/2022/06/image-facedetect-cdn-support.md) 21 de junio de 2022
* [Cómo empezar con la Transloadit Smart CDN](/es/blog/2024/02/getting-started-with-tlcdn.md) 16 de febrero de 2024
* [Ahorra costos con encoding de video bajo demanda](/es/blog/2025/05/on-demand-video-encoding.md) 5 de mayo de 2025
