saas-veille / lib /wpFetch.ts
PrestaGhis's picture
Create wpFetch.ts
232fb2d verified
Raw
History Blame Contribute Delete
2.38 kB
/**
* 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(' | ')}`
);
}