Fetch API JavaScript : Le Guide Complet pour les Requêtes HTTP

Fetch API JavaScript : Le Guide Complet pour les Requêtes HTTP

Introduction à l'API Fetch

L'API Fetch est l'interface moderne de JavaScript pour effectuer des requêtes HTTP depuis le navigateur. Elle remplace avantageusement l'ancien XMLHttpRequest avec une syntaxe plus propre basée sur les Promises, compatible avec async/await.

Requête GET basique

// Syntaxe de base
fetch('https://api.example.com/data')
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error('Erreur:', error));

// Avec async/await (recommandé)
async function fetchData() {
    try {
        const response = await fetch('https://api.example.com/data');

        if (!response.ok) {
            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }

        const data = await response.json();
        console.log(data);
        return data;
    } catch (error) {
        console.error('Erreur de fetch:', error);
    }
}

Les méthodes HTTP avec Fetch

GET : récupérer des données

// GET avec paramètres d'URL
const params = new URLSearchParams({
    page: 1,
    limit: 10,
    search: 'javascript'
});

const response = await fetch(`https://api.example.com/posts?${params}`);
const posts = await response.json();

POST : envoyer des données

// POST avec JSON
const response = await fetch('https://api.example.com/posts', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer YOUR_TOKEN'
    },
    body: JSON.stringify({
        title: 'Mon article',
        content: 'Contenu de l\'article',
        author: 'Tourak Digital'
    })
});

const newPost = await response.json();

// POST avec FormData (pour les fichiers)
const formData = new FormData();
formData.append('name', 'John');
formData.append('avatar', fileInput.files[0]);

const response = await fetch('https://api.example.com/upload', {
    method: 'POST',
    body: formData // Pas besoin de Content-Type, le navigateur le gère
});

PUT et PATCH : modifier des données

// PUT : remplacement complet
await fetch('https://api.example.com/posts/42', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
        title: 'Titre modifié',
        content: 'Contenu mis à jour'
    })
});

// PATCH : modification partielle
await fetch('https://api.example.com/posts/42', {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ title: 'Nouveau titre uniquement' })
});

DELETE : supprimer des données

const response = await fetch('https://api.example.com/posts/42', {
    method: 'DELETE',
    headers: { 'Authorization': 'Bearer YOUR_TOKEN' }
});

if (response.ok) {
    console.log('Post supprimé avec succès');
}

L'objet Response en détail

const response = await fetch(url);

// Propriétés
response.ok;         // true si status 200-299
response.status;     // Code HTTP (200, 404, 500...)
response.statusText; // Message ('OK', 'Not Found'...)
response.url;        // URL finale (après redirections)
response.redirected; // true si redirigé
response.headers;    // Headers de réponse
response.type;       // 'basic', 'cors', 'opaque'

// Méthodes pour lire le corps (ne peut être lu qu'une seule fois !)
const json = await response.json();   // Parse en JSON
const text = await response.text();   // Texte brut
const blob = await response.blob();   // Données binaires
const buffer = await response.arrayBuffer(); // ArrayBuffer
const form = await response.formData(); // FormData

// Lire les headers
response.headers.get('Content-Type');
response.headers.get('X-Total-Count');
response.headers.has('Authorization');

Gestion robuste des erreurs

// ATTENTION : fetch ne rejette PAS la promesse pour les erreurs HTTP (404, 500)
// Il rejette uniquement pour les erreurs réseau

async function safeFetch(url, options = {}) {
    try {
        const response = await fetch(url, options);

        // Vérifier le code HTTP
        if (!response.ok) {
            const errorBody = await response.text();
            throw new Error(
                `HTTP ${response.status}: ${response.statusText}\n${errorBody}`
            );
        }

        // Vérifier le Content-Type
        const contentType = response.headers.get('Content-Type');
        if (contentType && contentType.includes('application/json')) {
            return await response.json();
        }
        return await response.text();

    } catch (error) {
        if (error.name === 'AbortError') {
            console.log('Requête annulée');
        } else if (error.name === 'TypeError') {
            console.error('Erreur réseau ou CORS:', error.message);
        } else {
            console.error('Erreur:', error.message);
        }
        throw error;
    }
}

Fonctionnalités avancées

Annuler une requête avec AbortController

const controller = new AbortController();

// Timeout automatique
const timeoutId = setTimeout(() => controller.abort(), 5000);

try {
    const response = await fetch(url, {
        signal: controller.signal
    });
    clearTimeout(timeoutId);
    const data = await response.json();
} catch (error) {
    if (error.name === 'AbortError') {
        console.log('Requête annulée (timeout 5s)');
    }
}

// Annulation manuelle (ex: changement de page)
function cleanup() {
    controller.abort();
}

Requêtes parallèles

// Promise.all : toutes doivent réussir
const [users, posts, comments] = await Promise.all([
    fetch('/api/users').then(r => r.json()),
    fetch('/api/posts').then(r => r.json()),
    fetch('/api/comments').then(r => r.json())
]);

// Promise.allSettled : récupère tout, même les erreurs
const results = await Promise.allSettled([
    fetch('/api/users').then(r => r.json()),
    fetch('/api/posts').then(r => r.json()),
    fetch('/api/broken').then(r => r.json())
]);

results.forEach(result => {
    if (result.status === 'fulfilled') {
        console.log('Succès:', result.value);
    } else {
        console.log('Échec:', result.reason);
    }
});

Intercepteur de requêtes (fetch wrapper)

// Créer un client API réutilisable
class ApiClient {
    constructor(baseUrl, defaultHeaders = {}) {
        this.baseUrl = baseUrl;
        this.defaultHeaders = defaultHeaders;
    }

    async request(endpoint, options = {}) {
        const url = `${this.baseUrl}${endpoint}`;
        const config = {
            ...options,
            headers: {
                'Content-Type': 'application/json',
                ...this.defaultHeaders,
                ...options.headers
            }
        };

        if (config.body && typeof config.body === 'object') {
            config.body = JSON.stringify(config.body);
        }

        const response = await fetch(url, config);
        if (!response.ok) throw new Error(`HTTP ${response.status}`);
        return response.json();
    }

    get(endpoint)          { return this.request(endpoint); }
    post(endpoint, body)   { return this.request(endpoint, { method: 'POST', body }); }
    put(endpoint, body)    { return this.request(endpoint, { method: 'PUT', body }); }
    delete(endpoint)       { return this.request(endpoint, { method: 'DELETE' }); }
}

// Utilisation
const api = new ApiClient('https://api.example.com', {
    'Authorization': 'Bearer TOKEN'
});

const posts = await api.get('/posts');
const newPost = await api.post('/posts', { title: 'Nouveau' });

Fetch vs Axios vs XMLHttpRequest

CritèreFetchAxiosXMLHttpRequest
NatifOuiNon (librairie)Oui
PromisesOuiOuiNon (callbacks)
AnnulationAbortControllerCancelToken / AbortControllerabort()
IntercepteursManuelIntégrésManuel
Gestion erreurs HTTPManuelle (response.ok)AutomatiqueManuelle
Progress uploadNon natifOuiOui
Taille0 Ko~13 Ko0 Ko
RecommandéProjets légersApps complexesLegacy

Conclusion

L'API Fetch est l'outil natif et moderne pour les requêtes HTTP en JavaScript. Avec async/await, AbortController et une bonne gestion des erreurs, elle couvre la majorité des besoins. Pour les projets plus complexes nécessitant des intercepteurs ou le suivi de progression, Axios reste un excellent complément.

Chez Tourak Digital, nous développons des applications web performantes avec les meilleures pratiques JavaScript. Contactez-nous.

SEO Création Web Google Ads Marketing Blog À propos
Liens rapides
Informations
Tourak Digital Group