Cette page a été traduite à partir de l'anglais par la communauté. Vous pouvez contribuer en rejoignant la communauté francophone sur MDN Web Docs.

View in English Always switch to English

Méthode de requête QUERY

La méthode HTTP QUERY initie une requête côté serveur. Elle demande que la ressource cible traite le contenu de la requête de manière sûre et idempotente, en renvoyant le résultat dans la réponse.

La requête a un corps Oui
La réponse de succès a un corps Oui
Sûre Oui
Idempotente Oui
Mise en cache Oui
Autorisé dans les formulaires HTML Non

Syntaxe

http
QUERY <request-target>["?"<query>] HTTP/1.1
<request-target>

Identifie la ressource cible qui traite la requête lorsqu'elle est combinée avec les informations fournies dans l'en-tête Host. Il s'agit d'un chemin absolu (par exemple, /path/to/resource) dans les requêtes à un serveur d'origine, et d'une URL absolue dans les requêtes aux mandataires (par exemple, https://example.com/path/to/resource).

<query> Facultatif

Une composante de requête URI optionnelle précédée d'un point d'interrogation (?). Cela aide à identifier la ressource interrogée ; le contenu de la requête et son type de média définissent la requête réelle.

Description

La méthode QUERY demande à la ressource cible d'exécuter une opération de requête dans son propre périmètre et de retourner le résultat. Cela contraste avec GET, qui demande une représentation de la ressource identifiée par l'URI cible. Le contenu de la requête et son Content-Type définissent la requête ; la ressource cible détermine sur quoi la requête est exécutée, par exemple une table de base de données, un index de recherche ou une collection exposée par une API.

Comme la requête transite dans le contenu de la requête plutôt que dans l'URI, elle n'est pas limitée par les contraintes de longueur et d'encodage qui s'appliquent à une composante de requête URI. Elle est également moins largement exposée qu'une requête dans l'URI ; voir Considérations de sécurité pour plus de détails.

QUERY n'est pas un remplacement de GET dans tous les cas. Lorsque la requête est suffisamment petite pour tenir dans l'URI, GET reste un bon choix : il produit une URL qui peut être mise en favori, liée et mise en cache sans travail supplémentaire. QUERY est particulièrement utile lorsque l'URI devient impraticable, par exemple pour des requêtes volumineuses ou structurées comme une instruction SQL ou une expression JSONPath, ou pour des requêtes qui ne doivent pas être exposées dans l'URI.

En transportant du contenu, QUERY ressemble à POST, mais contrairement à POST, elle est explicitement sûre et idempotente. Un client ne demande ni n'attend aucun changement de la ressource cible ; vous pouvez donc réessayer les requêtes QUERY après une défaillance de connexion sans craindre d'effets supplémentaires.

Découvrir la prise en charge

Une ressource annonce la prise en charge de QUERY comme pour toute autre méthode, par la méthode OPTIONS et l'en-tête de réponse Allow.

Un client peut interroger une ressource pour connaître ses options comme ceci :

http
OPTIONS /contacts HTTP/1.1
Host: example.org

La ressource peut répondre ainsi pour indiquer qu'elle accepte les requêtes QUERY :

http
HTTP/1.1 200 OK
Allow: GET, QUERY, OPTIONS, HEAD

Un client peut envoyer la requête QUERY sans savoir si elle est prise en charge. Le serveur la traite soit normalement, soit répond avec 405 Method Not Allowed, accompagné d'un en-tête Allow listant les méthodes qu'il prend en charge.

Les formats de requête acceptés par une ressource sont annoncés séparément, par l'en-tête de réponse Accept-Query. Le client peut lire les formats acceptés à partir de l'en-tête Accept-Query.

Par exemple, une ressource peut annoncer les formats qu'elle accepte ainsi :

http
HTTP/1.1 200 OK
Allow: GET, QUERY, OPTIONS, HEAD
Accept-Query: application/x-www-form-urlencoded, application/sql

Un client peut alors envoyer une requête QUERY dans l'un de ces formats :

http
QUERY /contacts HTTP/1.1
Host: example.org
Content-Type: application/sql
Accept: application/json

SELECT surname, email FROM contacts LIMIT 10

Alternativement, le client peut envoyer la requête QUERY avec le format souhaité et lire les types de médias pris en charge à partir de l'en-tête Accept de la réponse 415 Unsupported Media Type résultante.

Types de médias et réponses d'erreur

Un serveur doit rejeter une requête QUERY dont le Content-Type est manquant ou incohérent avec le contenu de la requête. Les serveurs ne peuvent pas deviner le type de média à partir du contenu lui-même. La réponse dépend de la manière dont la requête est mal formée :

  • 400 Bad Request : La requête ne contient aucune information sur le type de média, ou le type de média déclaré est incohérent avec le contenu réel.
  • 415 Unsupported Media Type : Le type de média n'est pas pris en charge par la ressource. Cela inclut les cas où le type est compris en général mais n'a aucun sens en tant que requête pour cette ressource.
  • 422 Unprocessable Content : Le type de média est compris, et le contenu correspond à ce type, mais la requête elle-même ne peut pas être traitée — par exemple, une requête SQL syntaxiquement valide faisant référence à une table qui n'existe pas.
  • 406 Not Acceptable : Le client a demandé un type de média de réponse avec Accept que la ressource ne peut pas produire.

Ressources équivalentes

La ressource équivalente d'une requête QUERY est une ressource qui répond à GET et représente la requête QUERY, y compris sa cible et son contenu. Son objectif est de permettre à un client de répéter la même requête plus tard avec une simple requête GET, sans retourner le contenu de la requête. En effet, c'est la ressource à laquelle QUERY s'adresse, avec le contenu de la requête intégré dans son identité.

La ressource équivalente existe toujours conceptuellement, mais les serveurs ne sont pas obligés de lui attribuer un URI. Lorsqu'un serveur la représente à un URI, une réponse réussie à une requête QUERY peut y faire référence, ainsi qu'à une copie stockée du résultat, au moyen de deux en-têtes différents :

  • Content-Location : Identifie une ressource contenant le résultat de la requête vient d'être effectuée. Un GET vers cet URI récupère à nouveau les mêmes résultats.
  • Location : Identifie la ressource équivalente, qui relance la même requête. Un GET vers cet URI répète l'opération sur les données actuelles sans retourner le contenu de la requête ; par conséquent, le résultat peut différer de la réponse originale.

Aucune de ces ressources n'est garantie d'être permanente. Si une requête ultérieure vers l'une d'elles échoue, le client peut revenir à la répétition de la requête QUERY originale avec son contenu initial.

Comme ces URI représentent une requête, un serveur traitant un contenu de requête sensible doit les générer sans intégrer de partie sensible du contenu. Si ce n'est pas le cas, la requête est retournée dans une URI, perdant ainsi l'avantage de confidentialité décrit dans Considérations de sécurité.

Redirection

Un serveur peut répondre à une requête QUERY de manière indirecte en redirigeant le client. Avec 301 Moved Permanently, 308 Permanent Redirect, 302 Found ou 307 Temporary Redirect, le client est censé envoyer une requête QUERY similaire à l'URI indiqué dans Location. Historiquement, les clients suivant une redirection 301 ou 302 ont été autorisés à transformer une requête POST en requête GET. Cela ne s'applique pas à QUERY : pour les quatre codes de statut ci-dessus, la requête redirigée reste une requête QUERY avec le même contenu.

Une réponse 303 See Other signifie que la requête peut plutôt être satisfaite par un simple GET vers l'URI indiqué dans Location. Le 303 lui-même n'inclut pas de résultat de requête, permettant au serveur de retourner une ressource équivalente sans calculer la réponse en incise.

Requêtes conditionnelles

A représentation sélectionnée d'une requête QUERY est la même que celle d'un GET vers sa ressource équivalente. Une requête QUERY conditionnelle se comporte donc comme prévu : les résultats de la requête sont retournés uniquement si la condition dans des en-têtes tels que If-None-Match ou If-Modified-Since est remplie ; un 304 Not Modified est retourné sinon. Cela permet à un client de relancer une requête coûteuse tout en évitant le coût de transfert d'un résultat inchangé.

Mise en cache

Les réponses à une requête QUERY sont mises en cache, mais la clé de cache doit intégrer le contenu de la requête et ses métadonnées associées, car l'URI de la requête seule n'identifie plus la requête. Un cache doit donc lire l'intégralité du contenu de la requête avant de pouvoir faire correspondre une réponse stockée, ce qui rend la mise en cache des requêtes QUERY plus complexe que celle des requêtes GET. Les serveurs dont les réponses dépendent du contenu de la requête l'indiquent avec l'en-tête Vary. Vary indique aux caches que la réponse dépend de plus que de l'URI. Dans l'exemple suivant, une réponse stockée ne peut être réutilisée que pour une requête dont les valeurs des champs d'en-tête listés correspondent.

http
Vary: Accept-Query, Content-Encoding, Content-Type

Pour améliorer leur taux de réussite, les caches peuvent normaliser les différences sémantiquement insignifiantes dans le contenu de la requête avant de dériver la clé, comme la suppression d'un encodage de contenu. Cette normalisation n'est sûre que si elle correspond à la manière dont la ressource elle-même interprète le contenu. Un cache qui normalise de manière incorrecte, ou d'une manière qui diffère sensiblement de la ressource, peut traiter deux requêtes comme équivalentes alors qu'elles ne le sont pas et servir la mauvaise réponse. Un client qui doit empêcher la normalisation peut envoyer Cache-Control avec la directive no-transform, bien que la directive ne soit que consultative.

Lorsqu'une réponse fournit un en-tête Location identifiant une ressource équivalente, les clients peuvent passer à GET pour les requêtes ultérieures et se fier à la mise en cache ordinaire des GET à la place.

Considérations de sécurité

QUERY transporte ses données d'entrée dans le contenu de la requête plutôt que dans l'URI. Une URI est plus susceptible d'être enregistrée ou autrement traitée par des intermédiaires que le contenu de la requête, donc déplacer une requête hors de l'URI réduit sa diffusion. Pour cette raison, QUERY doit être privilégié par rapport à GET pour les requêtes confidentielles.

Cet avantage ne tient que si le reste de l'échange le préserve ; notez les contraintes sur les URI de ressources équivalentes et la normalisation du cache décrites ci-dessus.

Exemples

Interroger une collection

La requête suivante interroge une collection de contacts. Le contenu de la requête sélectionne trois champs, limite la réponse à dix résultats et filtre les contacts par adresse courriel :

http
QUERY /contacts HTTP/1.1
Host: example.org
Content-Type: application/x-www-form-urlencoded
Accept: application/json

select=surname,givenName,email&limit=10&email=%2A%40example.%2A

Une réponse réussie inclut le résultat de la requête dans le contenu de la réponse :

http
HTTP/1.1 200 OK
Content-Type: application/json

[
  {
    "surname": "Smith",
    "givenName": "Sandra",
    "email": "smith@example.org"
  },
  {
    "surname": "Biche",
    "givenName": "Jean",
    "email": "jean.biche@example.com"
  }
]

Réutiliser un résultat et répéter une requête

Un serveur peut retourner à la fois Content-Location et Location avec le résultat, offrant deux ressources différentes adressables par GET : une copie stockée de ce résultat, et la ressource équivalente, qui relance la requête :

http
HTTP/1.1 200 OK
Content-Type: application/json
Content-Location: /contacts/stored-results/17
Location: /contacts/stored-queries/42
Last-Modified: Sat, 25 Aug 2012 23:34:45 GMT

[
  {
    "surname": "Smith",
    "givenName": "Sandra",
    "email": "smith@example.org"
  },
  {
    "surname": "Biche",
    "givenName": "Jean",
    "email": "jean.biche@example.com"
  }
]

Un GET de l'URI Content-Location retourne le résultat stocké de cette requête particulière, inchangé :

http
GET /contacts/stored-results/17 HTTP/1.1
Host: example.org
Accept: application/json

Un GET de l'URI Location relance la requête, de sorte que le résultat reflète les données actuelles. Ici, un contact a été supprimé depuis la requête originale, et la réponse comporte un ETag à utiliser dans les requêtes conditionnelles ultérieures :

http
HTTP/1.1 200 OK
Content-Type: application/json
Last-Modified: Sun, 17 Nov 2024 16:12:01 GMT
ETag: "42-1"

[
  {
    "surname": "Smith",
    "givenName": "Sandra",
    "email": "smith@example.org"
  }
]

Une requête GET conditionnelle ultérieure envoyant If-None-Match: "42-1" retourne 304 Not Modified si le résultat est inchangé.

Spécifications

Spécification
Unknown specification
# name-query-method

Compatibilité des navigateurs

La compatibilité des navigateurs n'est pas pertinente pour cette méthode. Les navigateurs n'ont pas de support d'intégration spécifique pour QUERY : elle n'est pas envoyée pour les actions initiées par l'utilisateur·ice comme les envois de formulaires HTML, et les navigateurs ne l'envoient pas automatiquement en réponse à d'autres en-têtes ou mécanismes.

Les développeur·euse·s peuvent émettre une requête QUERY en utilisant fetch(). Notez que comme QUERY n'est pas l'une des méthodes CORS considérées comme sûres, les requêtes inter-origines déclenchent une requête CORS préliminaire OPTIONS, de la même manière que pour les autres méthodes non simples.

Voir aussi