¿Por qué la especificación HTML \ DOM no permite que los hipervínculos establezcan un encabezado de aceptación?

10

El propósito del Acceptencabezado 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/csvencabezado 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 Acceptencabezado a través del marcado?

Andy Hunt
fuente
2
Web es una plataforma heredada obstaculizada por el miedo al cambio y un comité de estándares lento: wtfhtmlcss.com wtfjs.com
Den

Respuestas:

9

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 útiles Accept-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

Copy Link Address

$ wgetPasteEnter

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 Acceptencabezado, porque la mayoría de los recursos solo tienen su formato y no tienen mucho sentido en otro. El Accept-Encodinges útil; si el cliente dice Accept-Encoding: gzip,deflateque significa que puede hacer una descompresión transparente . Pero el único uso en el que podría pensar Acceptes en formatos de imagen y video, por ejemplo, para proporcionar una alternativa para los navegadores que no son compatibles con say image/svg+xmlo video/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.

Jan Hudec
fuente
Además, con audio y video están las etiquetas audioy video. Así que ese problema ahora se mitiga (con suerte) hasta el punto de ser solucionado. Bueno, para navegadores compatibles con HTML5.
Parthian Shot
@ParthianShot: Cierto. No hago aplicaciones web, así que no recuerdo cómo funciona. Aparentemente es más adecuado proporcionar al cliente una lista para elegir (que generalmente es corta) que hacer que el cliente enumere todas las cosas que admite.
Jan Hudec
La URL debe identificar el recurso, esta es exactamente la razón por la que quería agregar parámetros como encabezado que sean útiles para rastrear cosas del usuario, como dónde estaba cuando hizo clic o si previamente fue redirigido desde algún lugar, ¿hay una mejor manera de hacerlo? ¿esta?
santiago arizti
3

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:

Accept: image/jpeg,image/tiff

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.

jimwise
fuente
Bingo. La aplicación no puede decidir qué tipos MIME acepta el navegador.
svidgen
2

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-Encodingde gzipno garantiza que la respuesta se comprima. Una Accept-Languagede ur-PKes 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 el Authorizationencabezado 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 Acceptencabezado no es diferente. Si un cliente especifica application/xmly el servidor solo es compatible application/json, entonces el servidor enviará JSON, no XML. Más importante aún, el Acceptencabezado 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-LanguageEs 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 mismo Accept-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.

Aaronaught
fuente
Si un cliente especifica application / xml y el servidor solo admite application / json, entonces el servidor enviará JSON, no XML. Entonces, ¿para qué sirve el error 406 HTTP? Para citar rfc2616: Si está presente un campo de encabezado Aceptar, y si el servidor no puede enviar una respuesta que sea aceptable de acuerdo con el valor combinado del campo Aceptar, entonces el servidor DEBE enviar una respuesta 406 (no aceptable).
Jules Randolph
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. → ¿Y si el diseñador de la aplicación quiere participar en la negociación? ¿Hay alguna referencia en la que se afirma que el agente de usuario, es decir, el cliente debe ser y solo es el navegador web ? Me alegraría si pudieras ayudarme a entender esto.
Jules Randolph
0

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.

BobDalgleish
fuente
0

La razón es realmente bastante simple ...

Navegador

El Acceptsencabezado 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 accepteste nuevo tipo de contenido, digamos que cifró algo y lo envió como tipo de archivo, encrypted/myencryptionsu 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 contenido

Enlaces 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.

Martin Barker
fuente