/** * fetch vers WordPress tolérant aux protections anti-bot. * * Problème résolu : certains hébergeurs/WAF répondent 307 vers LA MÊME URL en posant * un cookie, et n'acceptent la requête qu'au second essai avec ce cookie. * Un navigateur le fait tout seul (cookie jar) ; Node/undici non → boucle infinie * « redirect count exceeded ». * * Ce helper suit les redirections manuellement ET conserve les cookies entre les essais. */ function mergeCookies(existing: string, setCookies: string[]): string { const jar = new Map(); for (const part of existing.split('; ').filter(Boolean)) { const [k, ...v] = part.split('='); if (k) jar.set(k.trim(), v.join('=')); } for (const sc of setCookies) { const pair = sc.split(';')[0]; // on ignore Path/Expires/HttpOnly… const [k, ...v] = pair.split('='); if (k && k.trim()) jar.set(k.trim(), v.join('=')); } return Array.from(jar.entries()).map(([k, v]) => `${k}=${v}`).join('; '); } function readSetCookies(res: Response): string[] { const anyHeaders = res.headers as any; if (typeof anyHeaders.getSetCookie === 'function') return anyHeaders.getSetCookie(); const single = res.headers.get('set-cookie'); return single ? [single] : []; } export async function wpFetch(url: string, init: RequestInit, max = 6): Promise { let current = url; let cookies = ''; const chain: string[] = []; for (let i = 0; i < max; i++) { const headers = new Headers(init.headers as HeadersInit); if (cookies) headers.set('Cookie', cookies); const res = await fetch(current, { ...init, headers, redirect: 'manual' }); // Mémorisation des cookies posés — c'est ce qui permet de sortir de la boucle const setCookies = readSetCookies(res); if (setCookies.length) cookies = mergeCookies(cookies, setCookies); if (res.status >= 300 && res.status < 400) { const loc = res.headers.get('location'); chain.push(`${res.status} → ${loc || '(sans Location)'}`); if (!loc) break; current = new URL(loc, current).toString(); continue; } return res; } throw new Error( `WordPress boucle malgré la gestion des cookies. Chaîne depuis ${url} : ${chain.join(' | ')}` ); }