El propósito del Accept
encabezado del cliente es decirle al servidor qué tipo de datos aceptará como respuesta a su solicitud. Podemos configurar este encabezado en llamadas HTTP asincrónicas en Javascript, pero no en HTML.
Por ejemplo, considere un enlace como <a href="https://softwareengineering.stackexchange.com/some/resource">Get as CSV</a>
. Si accept="text/csv"
se permitiera un atributo como , y el navegador interpretó que para enviar un Accept: text/csv
encabezado con esa solicitud, el servidor podría responder a la semántica de la solicitud. Sin él, podríamos crear un enlace como <a href="https://softwareengineering.stackexchange.com/some/resource?format=csv">Get as CSV</a>
, y el servidor debe responder al parámetro de cadena de consulta arbitraria en su lugar.
¿Cuáles son las razones, tanto técnicas como históricas, detrás de la especificación HTML \ DOM que no permite la configuración de un Accept
encabezado a través del marcado?
fuente
Respuestas:
Porque los encabezados no son parte de la URL. La URL debe identificar el recurso, por sí mismo, y debe hacerlo de manera única. Los encabezados
Accept
(y los más útilesAccept-Encoding
) no deberían afectar la semántica de la solicitud. Deben indicar las capacidades del cliente para que el servidor pueda formatear la respuesta en consecuencia.Si realiza una llamada HTTP desde JavaScript, su código JavaScript es el cliente, por lo que puede configurar encabezados. Pero para el enlace HTML, el navegador es el cliente y, por lo tanto, puede elegir.
Si desea proporcionar CSV a un usuario, el recurso vinculado generalmente debe estar en un formato fijo. Imagina que el usuario hace
Eso es algo legítimo para ellos por varias razones. Y como el enlace les prometió CSV, eso es lo que esperarán. Pero el wget no obtendrá ningún otro atributo del enlace. Solo la URL. Por lo tanto, la información debe estar codificada en la URL.
De hecho, no hay muchos usos para el
Accept
encabezado, porque la mayoría de los recursos solo tienen su formato y no tienen mucho sentido en otro. ElAccept-Encoding
es útil; si el cliente diceAccept-Encoding: gzip,deflate
que significa que puede hacer una descompresión transparente . Pero el único uso en el que podría pensarAccept
es en formatos de imagen y video, por ejemplo, para proporcionar una alternativa para los navegadores que no son compatibles con sayimage/svg+xml
ovideo/webm
. Excepto que los navegadores no parecen anunciar qué formatos de medios admiten, por lo que no funciona. Y HTML eligió implementar un mecanismo diferente, ligeramente más flexible de todos modos. Y pocos otros tipos de datos tienen varios formatos alternativos ampliamente implementados para elegir.fuente
audio
yvideo
. Así que ese problema ahora se mitiga (con suerte) hasta el punto de ser solucionado. Bueno, para navegadores compatibles con HTML5.Porque el
Accept:
encabezado está destinado a indicar qué tipos de documentos el navegador del usuario puede manejar correctamente, y esta no es información que usted, como autor de la página web, tenga.Específicamente, la razón por la cual el protocolo HTTP proporciona un encabezado Aceptar: es permitir seleccionar un tipo de archivo apropiado cuando el mismo documento está disponible en más de una forma. Supongamos que estoy vinculando a una imagen, por ejemplo; mi navegador puede mostrar imágenes JPEG o Tiff, pero puede que no tenga la capacidad de mostrar una imagen RAW. El navegador indicaría esto enviando los siguientes encabezados con una solicitud de imagen:
Ahora, si el servidor puede servir una imagen determinada como RAW o como TIFF, respondería con una versión TIFF de la imagen (y establecería el
Content-Type:
encabezado para indicar el tipo que eligió).¿Qué significaría para el autor de la página web anular las opciones que envía el navegador? Si
accept="image/raw"
tuviera que agregar un atributo hipotético , el navegador aún no podría mostrar una imagen en bruto, pero el servidor la enviaría.fuente
Un URI está destinado a identificar un recurso .
Recurso se refiere a lo que se está recuperando. En un sitio web, generalmente es una página . En una API REST, normalmente sería una entidad: persona, perfil, widget, foto, etc.
Los encabezados HTTP le dicen al servidor cosas sobre el cliente : no describen nada sobre el recurso en sí, ni proporcionan ayuda para localizar ese recurso.
Por ejemplo:
Accept-Encoding
le dice al servidor que el cliente sabe cómo convertir o descomprimir cierto contenido.Accept-Language
le dice al servidor que el cliente está en un determinado entorno local y prefiere el contenido en ese entorno local.Authorization
le dice al servidor que el cliente cree que está autorizado para acceder a un recurso protegido.Un tema común con la mayoría de estos encabezados de solicitud es que el servidor no está obligado a cumplirlos. An
Accept-Encoding
degzip
no garantiza que la respuesta se comprima. UnaAccept-Language
deur-PK
es probable que se ignora cuando se golpea un sitio de Estados Unidos, a menos que específicamente apoyan urdu. Y el servidor se reserva el derecho de verificar elAuthorization
encabezado y devolver un 401 o 403 de todos modos, si no le gusta lo que ve.Ninguno de estos encabezados está destinado a cambiar materialmente nada sobre qué recurso proporciona el servidor en respuesta. El
Accept
encabezado no es diferente. Si un cliente especificaapplication/xml
y el servidor solo es compatibleapplication/json
, entonces el servidor enviará JSON, no XML. Más importante aún, elAccept
encabezado puede especificar varios tipos, en cuyo caso el servidor es libre de devolver lo que prefiera (o ninguno de ellos). Como puede imaginar, esto podría conducir fácilmente a un comportamiento indefinido para el usuario, pero ignoremos eso por el momento.La intención de un hipervínculo es vincular a una página ; la página es un cierto tipo de recurso. O bien, podría estar justificado en la definición más flexible de simplemente vincular a un recurso, incluso si ese recurso no es una página (tal vez una imagen o un conjunto de datos). Sin embargo, lo que definitivamente no está destinado a hacer es un enlace a una representación específica de un recurso. Eso es para que el cliente y el servidor negocien, y el servidor finalmente decida.
Accept-Language
Es un ejemplo obvio de por qué podría ser problemático permitir que los hipervínculos controlen los encabezados. Realmente no tiene sentido, si lo piensas. Cada usuario controla su preferencia de idioma; está configurado en el sistema operativo y / o el navegador. El navegador siempre debe enviar el mismoAccept-Language
encabezado, independientemente de la página que se visite. Si el servidor admite ese idioma, genial; si no, responderá con el idioma que considere más cercano.Si esto pudiera cambiarse mediante hipervínculos, los enlaces entrantes podrían forzarlo a ingresar a la versión en chino del sitio, incluso cuando su navegador y sistema operativo no estén configurados para admitir ese idioma. Eso no tiene sentido. Si el sitio admite inglés y su navegador es inglés, debería responder en inglés, sin importar lo que diga el hipervínculo.
Del mismo modo, si su navegador sabe cómo mostrar XML como datos estructurados, y puede buscar XSL para que se vea bonito, pero realmente no sabe qué hacer con JSON que no sea volcarlo como texto sin formato, obligándolos a El contenido JSON a través de un enlace (si tal cosa fuera posible) es un comportamiento agresivo hostil para el usuario. El navegador siempre debe ser el que diga: "Sé cómo mostrar X, pero no Y, así que realmente preferiría que me dieras X".
Puedo entender por qué podría pensar que es lógico permitir que el usuario de un navegador anule esta decisión. Pero la verdad del asunto es que está pensando en algunos casos pequeños como descargar un informe; El 99% de las veces, cuando existe esta opción, el usuario no está calificado o no tiene información suficiente para hacerlo.
Para decirlo de manera ligeramente diferente, imagine que sus padres o abuelos van a descargar un archivo y se les pide que elijan text / csv o text / plain. ¿Es probable que sepan la diferencia? No sé cuál es el tuyo, pero el mío a menudo ni siquiera puede detectar la diferencia entre un anuncio de banner y un mensaje de error, por lo que no hay forma de que puedan tomar esta decisión de manera inteligente. Por otro lado, puede haber un rayo de esperanza si se les dan enlaces separados para descargar un "libro de Excel" o "Solo texto", que para ellos son recursos separados , no solo una representación diferente del mismo recurso, y los URI deberían reflejar eso.
No se puede confiar en que el usuario comprenda que estas dos cosas son en realidad el mismo recurso, pero una representación diferente. Y sin cambiar todo sobre la forma en que funciona la web hoy en día, no podemos asumir nada sobre lo que harán con ese hipervínculo. Pueden hacer clic, o pueden hacer clic con el botón derecho -> "guardar como", o pueden copiarlo y pegarlo en su barra de direcciones, o pueden estar usando un administrador de descargas, o aún pueden estar usando IE6, o pueden podría estar usando una tableta o dispositivo móvil fuera de marca con un navegador patentado ... y en muchos de estos casos, no van a obtener el contenido que desean, porque perderán la parte del hipervínculo que declara el tipo de contenido, o su navegador no lo admitirá.
¿Podría la especificación HTML haber sido diseñada hace 40 años para admitir un atributo de tipo contenido en hipervínculos? Tal vez, aunque como he descrito en los primeros párrafos, hubo fuertes razones en su contra, especialmente durante un tiempo en que el ancho de banda y los recursos del servidor eran escasos y la idea de poder descargar el mismo informe en múltiples formatos (o, francamente , descargando cualquier informe) honestamente no se le había ocurrido a nadie. Pero ciertamente en el mundo de hoy sería una locura intentar agregar algo así a la especificación; rompería completamente la compatibilidad con versiones anteriores y conduciría al temido "comportamiento indefinido" en todos los navegadores existentes.
fuente
La respuesta principal es que un enlace en una página web está destinado a ser presentado como una página web. Si el servidor web devuelve algún tipo que no sea una página renderizable (imagen, archivo descargado, etc.), entonces el contenido puede ser procesado por el navegador o no (puede guardarse como un archivo).
No hay forma de que un enlace en una página web que conduce a un archivo CSS o un archivo JavaScript, etc., se represente correctamente en un navegador.
Para lograr lo que sea que intente lograr (no dijo), puede crear un enlace que invoque una función de JavaScript que brinde la funcionalidad adicional que necesita.
fuente
La razón es realmente bastante simple ...
Navegador
El
Accepts
encabezado le dice al servidor que acepto y sé cómo mostrar este tipo de archivo / contenido de archivo ...Javascript
Por qué puede cambiar el encabezado al enviar una solicitud en JavaScript es que podría haber creado una forma de
accept
este nuevo tipo de contenido, digamos que cifró algo y lo envió como tipo de archivo,encrypted/myencryption
su JavaScript podría saber cómo descifrarlo para que pueda aceptarlo tipo de contenido, por lo que debe decirle al servidor que puede aceptar ese contenidoEnlaces de anclaje
<a></a>
No es más que decirle al navegador que obtenga el archivo en href y que lo procese, por lo que si el navegador no puede entenderlo, intente analizarlo y mostrar un mensaje de descarga para el archivo. algunos servidores evitan esto simplemente configurando el tipo en text / plain y luego el navegador solo mostrará el texto del archivo.
fuente