diff options
Diffstat (limited to 'files/fr/web/api/fetch_api/using_fetch/index.md')
-rw-r--r-- | files/fr/web/api/fetch_api/using_fetch/index.md | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/files/fr/web/api/fetch_api/using_fetch/index.md b/files/fr/web/api/fetch_api/using_fetch/index.md new file mode 100644 index 0000000000..04a5708c1a --- /dev/null +++ b/files/fr/web/api/fetch_api/using_fetch/index.md @@ -0,0 +1,310 @@ +--- +title: Utiliser Fetch +slug: Web/API/Fetch_API/Using_Fetch +tags: + - API + - BODY + - Expérimental(2) + - Fetch + - Guide + - Promesse + - Promise + - Response + - request +translation_of: Web/API/Fetch_API/Using_Fetch +--- +<p>{{DefaultAPISidebar("Fetch API")}}</p> + +<p>L'<a href="/fr/docs/Web/API/Fetch_API">API Fetch</a> fournit une interface JavaScript pour l'accès et la manipulation des parties de la pipeline HTTP, comme les requêtes et les réponses. Cela fournit aussi une méthode globale {{domxref("GlobalFetch.fetch","fetch()")}} qui procure un moyen facile et logique de récupérer des ressources à travers le réseau de manière asynchrone.</p> + +<p>Ce genre de fonctionnalité était auparavant réalisé avec {{domxref("XMLHttpRequest")}}. Fetch fournit une meilleure alternative qui peut être utilisée facilement par d’autres technologies comme {{domxref("ServiceWorker_API", "Service Workers")}}. Fetch fournit aussi un endroit unique et logique pour la définition d'autres concepts liés à HTTP comme CORS et les extensions d'HTTP.</p> + +<h2 id="Létat_actuel_du_support_par_les_navigateurs">L'état actuel du support par les navigateurs</h2> + +<p>Le support de Fetch est à ses débuts, mais les choses progressent. Il a été activé par défaut sur Firefox 39 et supérieur, et sur Chrome 42 et supérieur.</p> + +<p>Si vous souhaitez l'utiliser maintenant, il y a un <a href="https://github.com/github/fetch">polyfill Fetch</a> disponible qui recrée la fonctionnalité pour les navigateurs qui ne le supportent pas. Gardez à l'esprit qu'il est au stade expérimental et pas encore complètement fonctionnel.</p> + +<div class="note"> +<p><strong>Note :</strong> Certaines préoccupations ont été soulevées sur le fait que la <a href="https://fetch.spec.whatwg.org/">spécification de Fetch</a> est en contradition avec la <a href="https://streams.spec.whatwg.org/">spécification de Streams</a>; cependant, les prévisions montrent une intention d'intégrer Streams avec Fetch: pour plus d'informations reportez vous à <a href="https://github.com/yutakahirano/fetch-with-streams/">Fetch API integrated with Streams</a>.</p> +</div> + +<h2 id="Détection_de_la_fonctionnalité">Détection de la fonctionnalité</h2> + +<p>Le support de l'API Fetch peut être détecté en vérifiant l'existence de {{domxref("Headers")}}, {{domxref("Request")}}, {{domxref("Response")}} ou {{domxref("GlobalFetch.fetch","fetch()")}} sur la portée de {{domxref("Window")}} ou de {{domxref("Worker")}}. Par exemple, vous pouvez faire cela dans votre script :</p> + +<pre class="brush: js">if (window.fetch) { + // exécuter ma requête fetch ici +} else { + // Faire quelque chose avec XMLHttpRequest? +}</pre> + +<h2 id="Créer_une_requête_fetch">Créer une requête fetch</h2> + +<p>Une requête fetch basique est vraiment simple à initier. Jetez un coup d'œil au code suivant :</p> + +<pre class="brush: js">const myImage = document.querySelector('img'); + +fetch('flowers.jpg') +.then(function(response) { + return response.blob(); +}) +.then(function(myBlob) { + const objectURL = URL.createObjectURL(myBlob); + myImage.src = objectURL; +}); + +</pre> + +<p>Ici nous récupérons une image à travers le réseau et l'insérons dans un élément {{htmlelement("img")}}. L'utilisation la plus simple de <code>fetch()</code> prend un argument — le chemin de la ressource que nous souhaitons récupérer — et retourne une promesse (promise) contenant, en réponse, un objet (de type {{domxref("Response")}}).</p> + +<p>Bien sûr, il s'agit seulement d'une réponse HTTP, pas exactement de l'image. Pour extraire le contenu de l'image de la réponse, nous utilisons la méthode {{domxref("Body.blob","blob()")}} (définie sur le mixin {{domxref("Body")}}, qui est implémenté autant par les objets {{domxref("Request")}} que par les objets {{domxref("Response")}}).</p> + +<div class="note"> +<p><strong>Note :</strong> Le mixin Body a aussi des méthodes similaires pour extraire d'autres types contenu ; pour plus d'informations regardez la section {{anch("Corps")}}.</p> +</div> + +<p>Un objet <code>objectURL</code> est ensuite créé à partir du {{domxref("Blob")}} extrait, puis est inseré dans {{domxref("img")}}.</p> + +<p>Les requêtes Fetch sont controllées par la directive <code>connect-src</code> du <a href="/fr/docs/Security/CSP/CSP_policy_directives">Content Security Policy</a> plutôt que par la directive de la ressource dont il s’agit de la récupération.</p> + +<h3 id="Fournir_des_options_à_la_requête">Fournir des options à la requête</h3> + +<p>La méthode <code>fetch()</code> accepte un second paramètre, optionnel ; un objet <code>init</code> qui vous permet de contrôler un certain nombre de réglages :</p> + +<pre class="brush: js">var myHeaders = new Headers(); + +var myInit = { method: 'GET', + headers: myHeaders, + mode: 'cors', + cache: 'default' }; + +fetch('flowers.jpg',myInit) +.then(function(response) { + return response.blob(); +}) +.then(function(myBlob) { + var objectURL = URL.createObjectURL(myBlob); + myImage.src = objectURL; +}); + +</pre> + +<p>Reportez-vous à {{domxref("GlobalFetch.fetch","fetch()")}} pour la liste complète des options disponibles, et plus de détails.</p> + +<h3 id="Vérifier_que_la_récupération_a_réussi">Vérifier que la récupération a réussi</h3> + +<p>Une promesse {{domxref("GlobalFetch.fetch","fetch()")}} va retourner une {{jsxref("TypeError")}} quand un problème réseau s'est produit. Cependant, il peut aussi s'agir d'un problème de permission ou quelque chose de similaire — un code HTTP 404 ne constitue pas une erreur réseau, par exemple. Un bon test de la réussite de <code>fetch()</code> devrait inclure la vérification que la promesse soit résolue, puis vérifier que la propriété {{domxref("Response.ok")}} ait la valeur <em>true</em>. Le code devrait ressembler à ce qui suit:</p> + +<pre class="brush: js">fetch('flowers.jpg').then(function(response) { + if(response.ok) { + response.blob().then(function(myBlob) { + var objectURL = URL.createObjectURL(myBlob); + myImage.src = objectURL; + }); + } else { + console.log('Mauvaise réponse du réseau'); + } +}) +.catch(function(error) { + console.log('Il y a eu un problème avec l\'opération fetch: ' + error.message); +});</pre> + +<h3 id="Fournir_votre_propre_objet_requête">Fournir votre propre objet requête</h3> + +<p>Plutôt que de transmettre le chemin de la ressource que vous souhaitez récupérer avec l'appel <code>fetch()</code>, vous pouvez créer un objet de requête en utilisant le constructeur {{domxref("Request.Request","Request()")}}, et le transmettre à la méthode <code>fetch()</code> en tant qu’argument:</p> + +<pre class="brush: js">var myHeaders = new Headers(); + +var myInit = { method: 'GET', + headers: myHeaders, + mode: 'cors', + cache: 'default' }; + +var myRequest = new Request('flowers.jpg',myInit); + +fetch(myRequest,myInit) +.then(function(response) { + return response.blob(); +}) +.then(function(myBlob) { + var objectURL = URL.createObjectURL(myBlob); + myImage.src = objectURL; +});</pre> + +<p><code>Request()</code> accepte exactement les mêmes paramètres que la méthode <code>fetch()</code>. Vous pouvez même lui transmettre un objet Request existant pour en créer une copie :</p> + +<pre class="brush: js">var anotherRequest = new Request(myRequest,myInit);</pre> + +<p>C'est très pratique, si le corps de la requête et de la réponse ne sont utilisés qu'une fois seulement. Cette manière de faire une copie permet de ré-utiliser la requête/réponse, en changeant juste les options du <code>init</code> si nécessaire.</p> + +<div class="note"> +<p><strong>Note :</strong> Il y a aussi une méthode {{domxref("Request.clone","clone()")}} qui créer une copie. Cela a une sémantique légèrement différente à l'autre méthode de copie— La première va échouer si l'ancien corps de la requête a déjà été lu (même pour copier une réponse), alors qu'avec <code>clone()</code> non.</p> +</div> + +<h2 id="En-têtes_Headers">En-têtes (Headers)</h2> + +<p>L'interface {{domxref("Headers")}} vous permet de créer vos propres objets d'en-têtes via le constructeur {{domxref("Headers.Headers","Headers()")}}. Un objet en-tête est un simple ensemble de plusieurs clé-valeurs:</p> + +<pre class="brush: js">var content = "Hello World"; +var myHeaders = new Headers(); +myHeaders.append("Content-Type", "text/plain"); +myHeaders.append("Content-Length", content.length.toString()); +myHeaders.append("X-Custom-Header", "ProcessThisImmediately");</pre> + +<p>On peut atteindre le même résultat en transmettant un tableau de tableaux ou un objet littéral au constructeur:</p> + +<pre class="brush: js">myHeaders = new Headers({ + "Content-Type": "text/plain", + "Content-Length": content.length.toString(), + "X-Custom-Header": "ProcessThisImmediately", +});</pre> + +<p>Le contenu peut être interrogé et récupéré:</p> + +<pre class="brush: js">console.log(myHeaders.has("Content-Type")); // true +console.log(myHeaders.has("Set-Cookie")); // false +myHeaders.set("Content-Type", "text/html"); +myHeaders.append("X-Custom-Header", "AnotherValue"); + +console.log(myHeaders.get("Content-Length")); // 11 +console.log(myHeaders.getAll("X-Custom-Header")); // ["ProcessThisImmediately", "AnotherValue"] + +myHeaders.delete("X-Custom-Header"); +console.log(myHeaders.getAll("X-Custom-Header")); // [ ]</pre> + +<p>Certaines de ces opérations sont seulement utiles dans {{domxref("ServiceWorker_API","ServiceWorkers")}}, mais elles fournissent une bien meilleur API pour la manipulation des en-têtes.</p> + +<p>Toutes les méthodes d'en-tête provoquent une erreur TypeError si un nom d’en-tête utilisé n'est pas un nom d’en-tête HTTP valide. Les opérations de mutation vont provoquer une erreur TypeError si il y a une protection immutable (voir ci-dessous). Sinon elles vont échouer en silence. Par exemple :</p> + +<pre class="brush: js">var myResponse = Response.error(); +try { + myResponse.headers.set("Origin", "http://mybank.com"); +} catch(e) { + console.log("Ne peut pas prétendre être une banque!"); +}</pre> + +<p>Un bon cas d'utilisation des en-têtes est de vérifier que le type de contenu récupéré est correct avant de poursuivre le traitement. Par exemple:</p> + +<pre class="brush: js">fetch(myRequest).then(function(response) { + var contentType = response.headers.get("content-type"); + if(contentType && contentType.indexOf("application/json") !== -1) { + return response.json().then(function(json) { + // traitement du JSON + }); + } else { + console.log("Oops, nous n'avons pas du JSON!"); + } +});</pre> + +<h3 id="Protection_Guard">Protection (Guard)</h3> + +<p>Puisque les en-têtes peuvent être envoyés dans les requêtes et reçus dans les réponses, et ont diverses limitations sur quelles informations peuvent et doivent être mutables, les objets en-tête ont une propriété <em>guard</em>. Ce n'est pas exposé au Web, mais cela définit quelle opération de mutation est autorisée sur l'objet en-tête.</p> + +<p>Les valeurs possibles de la propriété <em>guard</em> sont:</p> + +<ul> + <li><code>none</code>: défaut.</li> + <li><code>request</code>: guard pour l’en-tête obtenu d'une requête ({{domxref("Request.headers")}}).</li> + <li><code>request-no-cors</code>: guard pour l'en-tête obtenu d'une requête créé avec {{domxref("Request.mode")}} <code>no-cors</code>.</li> + <li><code>response</code>: guard pour l'en-tête obtenu d'une réponse ({{domxref("Response.headers")}}).</li> + <li><code>immutable</code>: majoritairement utilisé pour les ServiceWorkers; retourne un objet en-tête en lecture seule.</li> +</ul> + +<div class="note"> +<p><strong>Note :</strong> Vous ne pouvez pas ajouter ou définir sur une requête protegée une en-tête <code>Content-Length</code>. De manière similaire, ajouter <code>Set-Cookie</code> dans l'en-tête de réponse n'est pas autorisé: les ServiceWorkers ne sont pas autorisés à gérer des cookies via des réponses synthétisées.</p> +</div> + +<h2 id="Réponses">Réponses</h2> + +<p>Comme vous l'avez vu ci-dessus, des instances de {{domxref("Response")}} sont retournées quand la promesse de <code>fetch()</code> est résolue.</p> + +<p>Elles peuvent aussi être programmées dans le code via JavaScript, mais c'est seulement utile concernant les {{domxref("ServiceWorker_API", "ServiceWorkers")}}, quand vous retournez, pour une requête reçue, une réponse personnalisée en utilisant la méthode {{domxref("FetchEvent.respondWith","respondWith()")}}:</p> + +<pre class="brush: js">var myBody = new Blob(); + +addEventListener('fetch', function(event) { + event.respondWith(new Response(myBody, { + headers: { "Content-Type" : "text/plain" } + }); +)});</pre> + +<p>Le constructeur {{domxref("Response.Response","Response()")}} prend deux arguments optionnels —le corps de la réponse, et un objet d'options (similaire à l'objet que {{domxref("Request.Request","Request()")}} accepte).</p> + +<p>Les propriétés de réponse les plus communes que vous allez utiliser sont:</p> + +<ul> + <li>{{domxref("Response.status")}} —Un entier (valeur par défaut 200) contenant le code de statut de la réponse.</li> + <li>{{domxref("Response.statusText")}} — Une chaine de caractères (valeur par défaut "OK"), qui correspond au message du statut HTTP.</li> + <li>{{domxref("Response.ok")}} —vu précedemment, c'est un raccourci pour vérifier que le code de statut et bien compris entre 200 et 299 inclus. Retourne un {{domxref("Boolean")}}.</li> +</ul> + +<div class="note"> +<p><strong>Note :</strong> La méthode statique {{domxref("Response.error","error()")}} retourne simplement une réponse d'erreur. De manière similaire, {{domxref("Response.redirect","redirect()")}} retourne une réponse de redirection vers une URL spécifique. Elles sont aussi pertinentes pour les Service Workers.</p> +</div> + +<h2 id="Corps">Corps</h2> + +<p>Autant une requête qu'une réponse peut contenir un corps avec des données. Un corps est une instance de n'importe lequel des types suivants:</p> + +<ul> + <li>{{domxref("ArrayBuffer")}}</li> + <li>{{domxref("ArrayBufferView")}} (Uint8Array et ses proches)</li> + <li>{{domxref("Blob")}}/Fichier</li> + <li>chaine de caractères</li> + <li>{{domxref("URLSearchParams")}}</li> + <li>{{domxref("FormData")}}</li> +</ul> + +<p>Le mixin {{domxref("Body")}} définit les méthodes suivantes pour extraire le corps (implémenté autant par la {{domxref("Request")}} que par la {{domxref("Response")}}). Elles retournent toutes une promesse qui sera éventuellement résolue avec le contenu actuel.</p> + +<ul> + <li>{{domxref("Body.arrayBuffer","arrayBuffer()")}}</li> + <li>{{domxref("Body.blob","blob()")}}</li> + <li>{{domxref("Body.json","json()")}}</li> + <li>{{domxref("Body.text","text()")}}</li> + <li>{{domxref("Body.formData","formData()")}}</li> +</ul> + +<p>Ceci rend l'usage de données non textuelles plus facile qu’avec XHR.</p> + +<p>Le corps des requêtes peut être défini en passant les paramètres du corps:</p> + +<pre class="brush: js">var form = new FormData(document.getElementById('login-form')); +fetch("/login", { + method: "POST", + body: form +})</pre> + +<p>Les Requêtes et Réponses (et par extension la fonction <code>fetch()</code>), vont tenter de déterminer le type de contenu. Une requête va automatiquement définir un en-tête <code>Content-Type</code> si rien n'est défini dans le dictionnaire [NDLT: configuration d'initialisation].</p> + +<h2 id="Spécifications">Spécifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Spécification</th> + <th scope="col">Statut</th> + <th scope="col">Commentaire</th> + </tr> + <tr> + <td>{{SpecName('Fetch')}}</td> + <td>{{Spec2('Fetch')}}</td> + <td>Définition initiale</td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilité_navigateur">Compatibilité navigateur</h2> + +<p>{{Compat("api.WindowOrWorkerGlobalScope.fetch")}}</p> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li><a href="/fr/docs/Web/API/ServiceWorker_API">API ServiceWorker</a></li> + <li><a href="/fr/docs/Web/HTTP/Access_control_CORS">HTTP access control (CORS)</a></li> + <li><a href="/fr/docs/Web/HTTP">HTTP</a></li> + <li><a href="https://github.com/github/fetch">Polyfill pour Fetch</a></li> + <li><a href="https://github.com/mdn/fetch-examples/">Exemples de Fetch sur Github</a></li> +</ul> |