Pregunta HTTP GET con cuerpo de solicitud


Estoy desarrollando un nuevo servicio web RESTful para nuestra aplicación.

Al hacer un GET en ciertas entidades, los clientes pueden solicitar los contenidos de la entidad. Si desean agregar algunos parámetros (por ejemplo, ordenar una lista), pueden agregar estos parámetros en la cadena de consulta.

Alternativamente, quiero que las personas puedan especificar estos parámetros en el cuerpo de la solicitud. HTTP / 1.1 no parece prohibir explícitamente esto. Esto les permitirá especificar más información, podría facilitar la especificación de solicitudes XML complejas.

Mis preguntas:

  • ¿Es esta una buena idea?
  • ¿Tendrán problemas los clientes HTTP con el uso de cuerpos de solicitud dentro de una solicitud GET?

http://tools.ietf.org/html/rfc2616


1410
2018-06-10 20:47


origen


Respuestas:


Comentario de Roy Fielding acerca de incluir un cuerpo con una solicitud GET.

Sí. En otras palabras, cualquier mensaje de solicitud HTTP puede contener   un cuerpo de mensaje, y por lo tanto debe analizar mensajes con eso en mente.   La semántica del servidor para GET, sin embargo, está restringida de tal manera que un cuerpo,   si hay alguno, no tiene ningún significado semántico para la solicitud. Los requisitos   en el análisis son independientes de los requisitos en la semántica de métodos.

Entonces, sí, puedes enviar un cuerpo con GET, y no, nunca es útil   para hacerlo

Esto es parte del diseño en capas de HTTP / 1.1 que se convertirá en   borrar de nuevo una vez que la especificación se particiona (trabajo en progreso).

.... Roy

Sí, puedes enviar un cuerpo de solicitud con GET pero no debería tener ningún significado. Si le das significado analizándolo en el servidor y cambiando tu respuesta en función de su contenido, entonces estás ignorando esta recomendación en la especificación HTTP / 1.1, sección 4.3:

[...] si el método de solicitud      no incluye la semántica definida para un cuerpo de entidad, entonces el      Cuerpo del mensaje DEBERÍA ser ignorado al manejar la solicitud.

Y la descripción del método GET en la especificación HTTP / 1.1, sección 9.3:

El método GET significa recuperar cualquier información ([...]) identificada por Request-URI.

que indica que el cuerpo de solicitud no es parte de la identificación del recurso en una solicitud GET, solo el URI de solicitud.


1200
2018-06-11 20:27



Mientras tu poder hacer eso, en la medida en que no esté explícitamente excluido por la especificación HTTP, sugeriría evitarlo simplemente porque las personas no esperan que las cosas funcionen de esa manera. Hay muchas fases en una cadena de solicitud de HTTP y, aunque "en su mayoría" se ajustan a las especificaciones de HTTP, lo único que se le garantiza es que se comportarán como lo usan tradicionalmente los navegadores web. (Estoy pensando en cosas como proxies transparentes, aceleradores, kits de herramientas A / V, etc.)

Este es el espíritu detrás de la Principio de robustez aproximadamente "sé liberal en lo que aceptas y conservador en lo que envías", no querrás superar los límites de una especificación sin una buena razón.

Sin embargo, si tienes una buena razón, ve por ello.


234
2018-06-10 20:53



Es probable que encuentre problemas si alguna vez intenta aprovechar el almacenamiento en caché. Los proxies no buscarán en el cuerpo GET para ver si los parámetros tienen un impacto en la respuesta.


116
2018-06-10 21:10



Ninguno cliente de reposo ni Consola REST apoyar esto, pero Curl hace.

los Especificación HTTP dice en la sección 4.3

Un cuerpo de mensaje NO DEBE incluirse en una solicitud si la especificación del método de solicitud (sección 5.1.1) no permite el envío de un cuerpo de entidad en las solicitudes.

Sección 5.1.1 nos redirige a la sección 9.x para los diversos métodos. Ninguno de ellos prohíbe explícitamente la inclusión de un cuerpo de mensaje. Sin embargo...

Sección 5.2 dice

El recurso exacto identificado por una solicitud de Internet se determina examinando tanto el URI de solicitud como el campo del encabezado del host.

y Sección 9.3 dice

El método GET significa recuperar cualquier información (en forma de una entidad) identificada por Request-URI.

Que en conjunto sugieren que al procesar una solicitud GET, un servidor no es necesario para examinar cualquier otra cosa que el campo URI de solicitud y encabezado de host.

En resumen, la especificación HTTP no evita que envíe un cuerpo de mensaje con GET, pero hay suficiente ambigüedad como para no sorprenderme si no fuera compatible con todos los servidores.


60
2018-03-27 10:41



Elasticsearch acepta solicitudes GET con un cuerpo. Incluso parece que esta es la forma preferida: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/common-options.html#_request_body_in_query_string

Algunas bibliotecas de cliente (como el controlador Ruby) pueden registrar el comando cry en stdout en modo de desarrollo y está usando esta sintaxis de manera extensiva.


36
2017-12-03 11:15



Lo que está tratando de lograr se ha hecho durante mucho tiempo con un método mucho más común, y uno que no se basa en el uso de una carga útil con GET.

Simplemente puede compilar su tipo de medio de búsqueda específico, o si quiere ser más RESTful, use algo como OpenSearch y envíe la solicitud al URI que el servidor le indicó, por ejemplo, / search. El servidor puede generar el resultado de búsqueda o construir el URI final y redirigir utilizando un 303.

Esto tiene la ventaja de seguir el método PRG tradicional, ayuda a los intermediarios de caché a almacenar en caché los resultados, etc.

Dicho esto, los URI están codificados de todos modos para cualquier cosa que no sea ASCII, y también lo son application / x-www-form-urlencoded y multipart / form-data. Recomiendo usar esto en lugar de crear otro formato json personalizado si tu intención es admitir escenarios ReSTful.


25
2018-06-10 22:47



¿Qué servidor lo ignorará? - Fijiaaron 30 de agosto de 12 a 21:27

Google por ejemplo, está yendo peor que ignorarlo, lo considerará una error!

Pruébelo usted mismo con un netcat simple:

$ netcat www.google.com 80
GET / HTTP/1.1
Host: www.google.com
Content-length: 6

1234

(El contenido 1234 es seguido por CR-LF, por lo que es un total de 6 bytes)

y obtendrás:

HTTP/1.1 400 Bad Request
Server: GFE/2.0
(....)
Error 400 (Bad Request)
400. That’s an error.
Your client has issued a malformed or illegal request. That’s all we know.

También recibes 400 Bad Request de Bing, Apple, etc. que son atendidos por AkamaiGhost.

Así que no aconsejaría usar solicitudes GET con una entidad física.


23
2018-06-29 21:26



Puedes enviar un GET con un cuerpo o enviar un mensaje POST y renunciar a la religiosidad REST (no es tan malo, hace 5 años solo había un miembro de esa fe, sus comentarios se vincularon anteriormente).

Tampoco son buenas decisiones, pero enviar un cuerpo GET puede evitar problemas para algunos clientes, y algunos servidores.

Hacer un POST puede tener obstáculos con algunos frameworks RESTish.

Julian Reschke sugirió anteriormente el uso de un encabezado HTTP no estándar como "SEARCH", que podría ser una solución elegante, excepto que es aún menos probable que sea compatible.

Puede ser más productivo listar clientes que pueden y no pueden hacer cada uno de los anteriores.

Clientes que no pueden enviar un GET con cuerpo (que yo sepa):

  • XmlHTTPRequest Fiddler

Clientes que pueden enviar un GET con cuerpo:

  • la mayoría de los navegadores

Servidores y bibliotecas que pueden recuperar un cuerpo de GET:

  • apache
  • PHP

Servidores (y proxies) que despojan a un cuerpo de GET:

  • ?

21
2017-08-30 21:41



De RFC 2616, sección 4.3, "Cuerpo del mensaje":

Un servidor DEBERÍA leer y reenviar un cuerpo de mensaje en cualquier solicitud; Si el   El método de solicitud no incluye la semántica definida para un cuerpo de entidad.   entonces el cuerpo del mensaje DEBE ser ignorado al manejar la solicitud.

Es decir, los servidores siempre deben leer cualquier cuerpo de solicitud proporcionado de la red (verificar Content-Length o leer un cuerpo fragmentado, etc.). Además, los apoderados deben enviar cualquier cuerpo de solicitud que reciban. Entonces, si el RFC define la semántica del cuerpo para el método dado, el servidor puede usar el cuerpo de la solicitud para generar una respuesta. Sin embargo, si el RFC no definir semántica para el cuerpo, entonces el servidor debe ignorarlo.

Esto está en línea con la cita de Fielding arriba.

Sección 9.3, "OBTENER", describe la semántica del método GET y no menciona los cuerpos de solicitud. Por lo tanto, un servidor debe ignorar cualquier cuerpo de solicitud que recibe en una solicitud GET.


16
2018-03-06 21:44