最近在写爬虫的时候,发现一些网站喜欢使用302重定向,并且在重定向的过程中种下cookie,如果重定向后不带上cookie , 很容易出现安全认证。于是封装了一个重定向携带cookie 函数。
const fetch = require('node-fetch');
const { CookieJar } = require('tough-cookie');
const { URL } = require('url');
const cookieJar = new CookieJar();
async function fetchWithRedirect(url, options = {}, prevDomain = '') {
const mergedOptions = {
...options,
redirect: 'manual', // 禁止自动跟随重定向
headers: {
...options.headers,
Cookie: await cookieJar.getCookieString(url), // 获取当前 URL 对应的 Cookie 字符串
},
};
const response = await fetch(url, mergedOptions);
if (response.status >= 300 && response.status < 400 && response.headers.get('location')) {
let redirectUrl = response.headers.get('location');
// 处理相对路径的重定向
if (!redirectUrl.startsWith('http')) {
const parsedUrl = new URL(url);
const prevOrigin = parsedUrl.origin || `${parsedUrl.protocol}//${parsedUrl.host}`;
redirectUrl = prevOrigin + redirectUrl;
}
// 更新 Cookie 管理器的状态,从响应中获取并设置 Cookie
const cookieHeaders = response.headers.raw()['set-cookie'] || [];
await Promise.all(cookieHeaders.map((cookie) => cookieJar.setCookie(cookie, redirectUrl)));
const redirectedResponse = await fetchWithRedirect(redirectUrl, options, new URL(redirectUrl).origin);
return redirectedResponse;
}
return response;
}