Spaces:
Running
Running
| /** | |
| * 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<string, string>(); | |
| 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<Response> { | |
| 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(' | ')}` | |
| ); | |
| } |