Skip to main content
Glama

Web Scraper MCP Server

headerManager.ts8.62 kB
/** * @class HeaderManager * @description 负责管理和维护针对不同域名的自定义HTTP请求头。 */ export class HeaderManager { private domainHeaders: Map<string, Record<string, string>> = new Map(); constructor() { // 初始化时,为一些常见网站预设好请求头,方便开箱即用。 this.initializeDefaultHeaders(); } /** * @method setHeaders * @description 为指定的域名设置或更新自定义请求头。 * 如果该域名已存在配置,则会将新的请求头与旧的合并,新值会覆盖旧值。 * @param {string} domain - 目标域名,可以是完整的URL或纯域名 (e.g., "https://github.com/features" or "github.com")。 * @param {Record<string, string>} headers - 一个包含请求头键值对的对象。 */ setHeaders(domain: string, headers: Record<string, string>): void { // 始终使用标准化的域名作为键,确保一致性。 const normalizedDomain = this.normalizeDomain(domain); // 获取该域名已有的请求头,如果不存在则返回空对象。 const existingHeaders = this.domainHeaders.get(normalizedDomain) || {}; // 使用对象展开语法合并新旧请求头,实现更新或添加。 const mergedHeaders = { ...existingHeaders, ...headers }; this.domainHeaders.set(normalizedDomain, mergedHeaders); } /** * @method getHeaders * @description 获取指定域名的所有自定义请求头。 * @param {string} domain - 目标域名。 * @returns {Record<string, string>} - 返回一个包含该域名请求头的对象,如果未配置则返回空对象。 */ getHeaders(domain: string): Record<string, string> { const normalizedDomain = this.normalizeDomain(domain); // 如果Map中找不到对应域名,返回一个空对象,避免调用方出错。 return this.domainHeaders.get(normalizedDomain) || {}; } /** * @method removeHeaders * @description 删除指定域名的所有请求头配置。 * @param {string} domain - 目标域名。 * @returns {boolean} - 如果成功删除则返回 true,否则返回 false。 */ removeHeaders(domain: string): boolean { const normalizedDomain = this.normalizeDomain(domain); return this.domainHeaders.delete(normalizedDomain); } /** * @method removeHeaderField * @description 从指定域名的配置中,移除单个请求头字段。 * @param {string} domain - 目标域名。 * @param {string} fieldName - 要移除的请求头字段名 (e.g., "User-Agent")。 * @returns {boolean} - 如果成功找到并移除了字段,则返回 true,否则返回 false。 */ removeHeaderField(domain: string, fieldName: string): boolean { const normalizedDomain = this.normalizeDomain(domain); const headers = this.domainHeaders.get(normalizedDomain); if (headers && fieldName in headers) { delete headers[fieldName]; return true; } return false; } /** * @method listDomains * @description 列出所有当前已配置自定义请求头的域名。 * @returns {string[]} - 返回一个包含所有已配置域名的字符串数组。 */ listDomains(): string[] { return Array.from(this.domainHeaders.keys()); } /** * @method getAllHeaders * @description 获取所有域名的完整请求头配置。 * @returns {Record<string, Record<string, string>>} - 返回一个对象,键是域名,值是对应的请求头对象。 */ getAllHeaders(): Record<string, Record<string, string>> { const result: Record<string, Record<string, string>> = {}; this.domainHeaders.forEach((headers, domain) => { // 返回一个深拷贝,防止外部修改影响内部状态 result[domain] = { ...headers }; }); return result; } /** * @private * @method normalizeDomain * @description 将输入的URL或域名字符串标准化处理,提取其核心域名部分。 * 例如: "https://www.example.com:8080/path/to/page" -> "www.example.com" * @param {string} domain - 原始域名或URL字符串。 * @returns {string} - 标准化后的域名,全小写。 */ private normalizeDomain(domain: string): string { // 1. 移除协议头 (http://, https://) let normalized = domain.replace(/^https?:\/\//, ""); // 2. 移除协议后的路径部分 normalized = normalized.split("/")[0]; // 3. 移除端口号 normalized = normalized.split(":")[0]; // 4. 统一转换为小写,便于匹配 return normalized.toLowerCase(); } /** * @private * @method initializeDefaultHeaders * @description 初始化一些常用网站的默认请求头,提供开箱即用的便利性。 */ private initializeDefaultHeaders(): void { // 为常见的内容平台设置一些基本的、无害的请求头,可以提高爬取成功率。 this.setHeaders("github.com", { Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", "Cache-Control": "no-cache", }); this.setHeaders("zhihu.com", { Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", Referer: "https://www.zhihu.com/", }); this.setHeaders("weibo.com", { Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", Referer: "https://weibo.com/", }); this.setHeaders("douban.com", { Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", Referer: "https://www.douban.com/", }); this.setHeaders("jianshu.com", { Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", Referer: "https://www.jianshu.com/", }); this.setHeaders("csdn.net", { Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", Referer: "https://www.csdn.net/", }); } /** * @method addAntiDetectionHeaders * @description 为指定域名添加一套通用的、模拟真实浏览器的请求头,用于对抗常见的反爬虫检测。 * @param {string} domain - 目标域名。 */ addAntiDetectionHeaders(domain: string): void { const antiDetectionHeaders = { Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6", "Cache-Control": "max-age=0", "Sec-Fetch-Dest": "document", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-Site": "none", "Sec-Fetch-User": "?1", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", }; this.setHeaders(domain, antiDetectionHeaders); } /** * @method setMobileHeaders * @description 为指定域名设置一套模拟移动端(iPhone)的请求头。 * @param {string} domain - 目标域名。 */ setMobileHeaders(domain: string): void { const mobileHeaders = { "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1", Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", "Accept-Encoding": "gzip, deflate, br", }; this.setHeaders(domain, mobileHeaders); } /** * @method setApiHeaders * @description 为指定域名设置一套适用于请求API接口的请求头。 * @param {string} domain - 目标域名。 * @param {string} [apiKey] - (可选) 如果API需要认证,可以提供Bearer Token。 */ setApiHeaders(domain: string, apiKey?: string): void { const apiHeaders: Record<string, string> = { Accept: "application/json, text/plain, */*", "Content-Type": "application/json", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", }; if (apiKey) { apiHeaders["Authorization"] = `Bearer ${apiKey}`; } this.setHeaders(domain, apiHeaders); } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/naku111/mcpServer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server