Content-Disposition
Uso
En una respuesta HTTP estándar, la cabecera Content-Disposition controla cómo presenta el navegador el contenido al usuario. Asignar el valor inline indica al navegador que renderice el contenido directamente. Asignar el valor attachment abre en su lugar un diálogo de descarga.
Esta cabecera también interviene en las respuestas multipart/form-data y en los envíos de formularios. Cada parte de un cuerpo multipart incluye su propio campo Content-Disposition, que identifica el nombre del campo del formulario y, opcionalmente, el nombre de archivo de los ficheros subidos. El límite entre partes se define en la cabecera Content-Type.
inline
La directiva inline indica al navegador que muestre el contenido directamente dentro de la página. Es el comportamiento predeterminado de la mayoría de las respuestas cuando no hay Content-Disposition.
attachment
La directiva attachment provoca un aviso de descarga. El navegador presenta un diálogo de “Guardar como” en lugar de renderizar el contenido en la ventana gráfica.
filename
El parámetro filename sugiere un nombre de archivo predeterminado para el fichero descargado. El valor se encierra entre comillas dobles y sigue las reglas de codificación ASCII.
Content-Disposition: attachment; filename="report.pdf"
filename*
El parámetro filename* amplía filename con soporte para codificaciones de caracteres más allá de ASCII. Cuando están presentes tanto filename como filename*, filename* tiene prioridad. Resulta útil para nombres de archivo que contienen caracteres no ASCII.
Content-Disposition: attachment; filename="document.pdf"; filename*=UTF-8''d%C3%B6cument.pdf
form-data
La directiva form-data aparece en las partes de un cuerpo multipart e identifica el contenido como perteneciente a un envío de formulario.
name
El parámetro name es obligatorio dentro de las partes de un cuerpo multipart e identifica el campo de formulario al que corresponde la parte.
Ejemplo
Un servidor que responde con la descarga de un archivo CSV establece attachment y proporciona un nombre de archivo sugerido. El navegador abre un diálogo de guardado con “export.csv” ya rellenado.
Content-Disposition: attachment; filename="export.csv"
Un servidor que muestra un PDF directamente en el navegador utiliza inline. El navegador renderiza el PDF en su visor integrado en lugar de descargar el archivo.
Content-Disposition: inline
En un envío de formulario multipart, cada parte lleva su propio campo Content-Disposition. El parámetro name asocia la parte con el campo de formulario correspondiente, y filename indica el nombre original del archivo subido.
Content-Disposition: form-data; name="avatar"; filename="photo.jpg"
Diagnóstico
Los problemas de descarga y visualización con Content-Disposition suelen deberse a valores de directiva incorrectos o a errores en la codificación del nombre de archivo.
El archivo se descarga con el nombre equivocado. El navegador usa el parámetro filename como nombre de guardado predeterminado. Un valor de filename ausente o mal formado hace que el navegador recurra a la ruta de la URL o a un nombre genérico. Asegúrese de que el valor esté entre comillas dobles: filename=“report.pdf”. Verifique la cabecera con curl -I https://example.re/file y revise el parámetro filename en la respuesta.
Los caracteres no ASCII del nombre de archivo se corrompen o se muestran como símbolos ilegibles. El parámetro filename solo admite caracteres ASCII. Para nombres con letras acentuadas, caracteres CJK u otro texto no ASCII, añada el parámetro filename* con la sintaxis de codificación: filename*=UTF-8”d%C3%B6cument.pdf. Incluya tanto filename (reserva en ASCII) como filename* (versión codificada) para lograr la máxima compatibilidad entre navegadores.
El navegador ignora attachment y muestra el contenido en línea. Algunos navegadores anulan attachment para los tipos de contenido que renderizan de forma nativa, como los PDF y las imágenes. La cabecera Content-Type influye en este comportamiento. Establecer Content-Type: application/octet-stream junto con attachment fuerza la descarga de cualquier tipo de archivo. Las extensiones del navegador y los visores integrados (PDF.js) también pueden anular la directiva.
Se produce la visualización en línea cuando se esperaba una descarga. Si falta la cabecera Content-Disposition, el valor predeterminado es inline para la mayoría de los tipos de contenido. El servidor debe enviar attachment de forma explícita para provocar una descarga. En nginx, añada add_header Content-Disposition “attachment”; al bloque location correspondiente. En Apache, use Header set Content-Disposition “attachment” dentro de una directiva
Precedencia entre filename y filename*. Cuando ambos parámetros están presentes, filename* tiene prioridad en todos los navegadores modernos. Los clientes antiguos que no admiten filename* recurren a filename. Incluya siempre ambos parámetros. El valor de filename* debe usar codificación porcentual para los caracteres especiales: filename*=UTF-8”na%C3%AFve.txt.
Métodos auxiliares de respuesta de descarga específicos de cada framework. La mayoría de los frameworks web ofrecen métodos integrados para establecer las cabeceras de descarga. Django usa FileResponse con el parámetro as_attachment. Express usa res.download(). Flask usa send_file() con as_attachment=True. Rails usa send_data o send_file con una opción disposition. Estos métodos se encargan de la codificación del nombre de archivo y del formato de la cabecera, lo que reduce la probabilidad de errores manuales.