2009-09-16 10 views
15

La pregunta principal es sobre el uso de los encabezados HTTP, incluidos Range, If-Range, Accept-Ranges y un especificador de rango definido por el usuario.¿Cómo utilizar el encabezado de rango HTTP con un especificador de rango distinto de los bytes?

Aquí hay un ejemplo fabricado para ayudar a ilustrar mi pregunta. Supongamos que tengo una aplicación de estilo Web 2.0 que muestra algún tipo de documentos legibles por humanos. Estos documentos están divididos editorialmente en páginas (similar a los artículos que se ven en los sitios web de noticias). Para este ejemplo, suponga:

  • Hay un documento titulado "HTTP Range Question" dividido en tres páginas.
  • La página del shell (/document/shell/http-range-question) conoce la metainformación sobre el documento, incluido el número de páginas.
  • La primera página legible del documento se carga durante el evento de carga de página a través de un Ajax GET y se inserta en la página.
  • Un control de IU que se parece a [1 2 3 Todo] está en la parte inferior de la página y al hacer clic en un número se mostrará esa página legible (también cargada mediante ajax) y al hacer clic en "Todos" se mostrará documento completo. Asumir estos Sitios en Internet de 1, 2, 3 y todos los casos de uso:
    • /document/content/http-range-question?page=1
    • /document/content/http-range-question?page=2
    • /document/content/http-range-question?page=3
    • /document/content/http-range-question

ahora a la cuestión. ¿Puedo usar los encabezados del rango HTTP en lugar de la URL (por ejemplo, un parámetro querystring)? Tal vez algo como esto en la solicitud GET /document/content/http-range-question:

Range: page=1 

Parece que la especificación sólo define byte varía según permitida, por lo que incluso si he hecho mis llamadas ajax funcionan con el navegador y el código del servidor, cualquier cosa en el medio podría romper el contrato (por ejemplo, un servidor proxy de almacenamiento en caché).

Range: bytes=0-499 

¿Alguna opinión o ejemplos del mundo real de especificadores de rango personalizados?

actualización: Lo que encontrar una pregunta similar sobre la cabecera de la gama (Paging in a Rest Collection), donde se menciona que Dojo JsonRestStore utiliza un valor de encabezado rango personalizado.

Range: items=0-24 
+0

posible duplicado de [Paging in a Rest Collection] (http://stackoverflow.com/questions/924472/paging-in-a-rest-collection) – DanMan

+0

@DanMan - Ya había vinculado a esa pregunta similar, pero no todo HTTP es REST y esto hace una pregunta sobre los valores permitidos, no la semántica de REST. Además, la redacción de diferentes títulos de preguntas ayuda a diferentes personas a encontrar sus respuestas. –

Respuesta

32

Absolutamente - puede especificar cualquier unidad de rango que desee.

De RFC 2616:

3,12 Unidades del Rango

HTTP/1.1 permite que un cliente solicite que sólo una parte (una serie de) la entidad
respuesta se incluirá dentro de la respuesta . HTTP/1.1 usa unidades de rango en el rango (sección 14.35) y Content-Range (sección 14.16)
campos de encabezado. Una entidad puede dividirse en subintervalos de acuerdo con varias unidades estructurales.

range-unit  = bytes-unit | other-range-unit 
    bytes-unit  = "bytes" 
    other-range-unit = token 

La única unidad de rango definido por HTTP/1.1 es "bytes". HTTP/1.1
implementaciones PUEDE ignorar rangos especificados utilizando otras unidades.

La pieza clave es el último párrafo. Realmente lo que está diciendo es que cuando escribieron las especificaciones para HTTP/1.1, solo delinearon el token de "bytes". Pero, como puede ver en el bit de 'otra unidad de rango', puede crear sus propios especificadores de tokens.

Programar con sus propios especificadores de rango significa que debe tener control sobre el cliente y el código de servidor que usa ese especificador. Por lo tanto, si posee la pieza de back-end que expone el URI "/ document/content/http-range-question", está listo; presumiblemente está usando un marco web moderno que le permite inspeccionar los encabezados de solicitud que ingresan. Luego, puede mirar los valores del Rango para realizar la consulta de respaldo correctamente.

Además, si controla el código AJAX que realiza las solicitudes al servidor, debería poder configurar el encabezado del rango usted mismo.

Sin embargo, hay una desventaja potencial que anticipa en su pregunta: la posibilidad de interrumpir el almacenamiento en caché. Si está utilizando una unidad de Rango personalizada, cualquier memoria caché entre su cliente y los servidores de origen "PUEDE ignorar los rangos especificados usando [unidades distintas de 'bytes']". Así que, por ejemplo, si tiene un caché de Squid/Varnish entre el frente y el back-end, ¡no hay garantía de que los resultados que espera sean servidos desde el caché!

También podría considerar una implementación alternativa en la que, en lugar de utilizar una cadena de consulta, la página se convierta en un "parámetro" del URI; por ejemplo,/document/content/http-range-question/page/1. Es probable que esto requiera un poco más de trabajo para usted, pero es compatible con HTTP/1.1 y las memorias caché deben tratarlo adecuadamente.

Espero que esto ayude.

+0

Buen punto en el almacenamiento en caché, pero para eso sirve el encabezado "variar". http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44 El problema más grande es que no es muy HATEOAS. –

-2

Parece que quiere cambiar la especificación HTTP solo para eliminar un parámetro querystring. Para hacer esto tendrías que modificar el código tanto en el cliente para enviar el encabezado modificado y el servidor para leer desde el encabezado "Rango" en lugar de la cadena de consulta.

El resultado final es que esto probablemente funcionará, pero está rompiendo todos los estándares y las herramientas existentes para hacerlo.

+4

Lo veo más como tratar de cumplir con el espíritu de la especificación en que una URL puede obtener todo el contenido o, utilizando un encabezado definido en la especificación, puede obtener partes lógicas del contenido (pero no segmentado por bytes). Sin embargo, es completamente posible que esta sea una mala idea incluso si pudiera hacer que funcione. –

+3

Estoy de acuerdo con Kevin y creo que la especificación es bastante clara de que esto es posible (¿por qué debería haber un campo Aceptar rangos en una respuesta que especifique las unidades de rango aceptadas por el servidor)? Adicionalmente al regresar, p. una colección de matriz JSON, la respuesta del rango de contenido puede dar el tamaño de todos los elementos, p. Content-Range: elementos 0-9/20, mientras que las soluciones querystring tienen que transferir de alguna manera esa información en otro lugar. – Daff

0

HTTP Range se utiliza normalmente para recuperar descargas interrumpidas sin comenzar desde el principio.

Lo que está tratando de hacer sería mejor manejado por OAI-ORE, que le permite definir las relaciones entre varios documentos. (formatos alternativos, componentes del todo, etc.)

Desafortunadamente, es un formato de metadatos relativamente nuevo, y no conozco ningún navegador web que se envíe con soporte nativo.

0

bytes es la única unidad compatible con la especificación HTTP 1.1.

+2

Sí, pero las nuevas unidades de rango son un punto de extensión –

+0

Las nuevas unidades de rango deben registrarse en el "Registro de unidades de rango" como se menciona en https://tools.ietf.org/html/rfc7233#section-2.2 Sin registro oficial cualquier otra unidad bytes o "ninguno" son inválidos. –

+0

De 7233: "Las nuevas unidades de rango * deben * estar registradas en IANA". (énfasis mío). "Ought" no está definido en . Si este fuera un requisito, incluso uno blando, ¿no lo habrían indicado con uno de los términos "DEBE", "REQUERIDO", "DEBERÁ", "DEBERÍA", o "RECOMENDADO"? –

Cuestiones relacionadas