码农札记

基于 Node.js 的 CSDN 文章列表获取代码解析

2025-05-08T09:58:46.000Z
85 views
2 min read
default

基于 Node.js 的 CSDN 文章列表获取代码解析

在开发过程中,与第三方 API 进行交互是常见的需求之一。本文将对一段用于获取 CSDN 文章列表的 Node.js 代码进行详细解析,帮助开发者理解其工作原理和实现细节。

代码功能概述

这段代码的主要功能是向 CSDN 的指定 API 发起 GET 请求,获取文章列表相关信息,包括文章的 ID、发布时间和标题等。在请求过程中,涉及到请求头部的处理、HMAC 签名的生成以及对 API 响应数据的解析和提取。

代码实现细节

1. 请求头部过滤

通过 filterHeaders 函数,从给定的请求头部对象中筛选出键名以 "x-ca-" 开头的头部信息。这些头部信息将在后续的签名生成过程中被用到。

javascript
const filterHeaders = (headers) => { const filteredHeaders = {}; for (const key in headers) { const lowerKey = key.toLowerCase(); if (lowerKey.startsWith("x-ca-")) { filteredHeaders[lowerKey] = headers[key]; } } return filteredHeaders; };

2. HMAC 签名生成

generateSignature 函数负责构建签名字符串并生成 HMAC 签名。签名字符串的构建过程如下:

  • 依次添加请求方法、接受内容类型、空行、内容类型、日期。
  • 处理请求头部,对筛选后的头部键进行排序,并按格式拼接到签名字符串中。
  • 处理 URL 和参数,对参数键进行排序,构建查询字符串,并与处理后的 URL 拼接。

最后,使用 CryptoJS 库的 HmacSHA256 方法生成签名,并将其转换为 Base64 编码的字符串。

javascript
const generateSignature = ({ method, url, appSecret, accept, date, contentType, params, headers }) => { let signatureString = `${method}\n${accept}\n\n${contentType}\n${date}\n`; // 处理请求头部 const filteredHeaders = filterHeaders(headers); const sortedHeaderKeys = Object.keys(filteredHeaders).sort(); for (const key of sortedHeaderKeys) { signatureString += `${key}:${filteredHeaders[key]}\n`; } // 处理 URL 和参数 const processedUrl = url.replace(/^(?=^.{3,255}$)(http(s)?:\/\/)?(www\.)?[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.csdn\.net)/, ""); const urlParams = new URLSearchParams(); const sortedParamKeys = Object.keys(params).sort(); for (const key of sortedParamKeys) { urlParams.append(key, params[key]); } signatureString += urlParams.toString() ? `${processedUrl}?${urlParams.toString()}` : processedUrl; // 生成 HMAC 签名 return CryptoJS.HmacSHA256(signatureString, appSecret).toString(CryptoJS.enc.Base64); };

3. 随机数生成

generateNonce 函数生成符合特定格式的随机数,用于请求的唯一标识。

javascript
const generateNonce = () => { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (char) => { const random = (16 * Math.random()) | 0; return (char === "x" ? random : (random & 3) | 8).toString(16); }); };

4. 发起请求

fetchCSDNArticles 函数中,首先生成随机数,构建 API 请求配置。然后通过 generateSignature 函数获取签名,设置请求头部。最后,使用 axios 库发起 GET 请求,并对响应数据进行处理,提取文章列表相关信息。

javascript
async function fetchCSDNArticles() { const nonce = generateNonce(); const apiConfig = { method: 'GET', url: 'https://bizapi.csdn.net/blog/phoenix/console/v1/article/list', appSecret: 'xxxx', accept: 'application/json, text/plain, */*', date: '', contentType: '', params: { page: 1, pageSize: 100, status: "all_v2" }, headers: { "Accept": "application/json, text/plain, */*", "Content-Type": "", "X-Ca-Key": "key", 'X-Ca-Nonce': nonce } }; const signature = generateSignature(apiConfig); const requestHeaders = { 'cookie': `cookie`, // 需替换有效 cookie 'x-ca-key': apiConfig.headers['X-Ca-Key'], 'x-ca-nonce': nonce, 'x-ca-signature': signature, "x-ca-signature-headers": "x-ca-key,x-ca-nonce", }; try { const response = await axios.get(apiConfig.url, { headers: requestHeaders, params: apiConfig.params }); const articles = response.data.data.list.map(item => ({ id: item.articleId, postTime: item.postTime, title: item.title })); return articles; } catch (error) { console.error('请求失败:', error.response?.data || error.message); return []; } }

使用示例

通过调用 fetchCSDNArticles 函数,并在其返回的 Promise 上使用 .then() 方法,可以获取到文章列表数据,并进行相应的处理和展示。

javascript
fetchCSDNArticles().then(articles => { console.log('文章列表:', articles); });

效果

在这里插入图片描述

注意事项

  1. 在实际使用中,需要将代码中的占位符(如 cookie 值)替换为有效的实际值,否则请求将无法通过验证。
  2. 由于网络环境或 CSDN API 的变动等因素,该代码可能无法直接运行成功。如果遇到问题,可以先检查网络连接、API 地址、参数配置等方面是否正确。
  3. CSDN 的 API 使用可能受到相关协议和规定的限制,请确保在合法合规的前提下使用该代码。

关于链接解析失败的说明

在代码中提到的链接 “https://bizapi.csdn.net/blog/phoenix/console/v1/article/list”,由于网络原因或链接本身的合法性问题,解析未能成功。如果您需要该网页的解析内容,请先检查网页链接的合法性和网络环境,适当重试。

免责声明

本文提供的代码仅供参考和学习,用于帮助开发者了解如何与 CSDN API 进行交互以及请求签名的生成过程。在实际使用中,请确保遵守 CSDN 的相关使用条款和规定,合法合规地使用其 API 服务。同时,代码中的部分参数(如 appSecret、apiKey、cookie 等)需要替换为实际有效的值才能正常运行,切勿使用未经授权的参数值。对于因使用本代码而引发的任何法律问题或纠纷,作者和发布平台不承担任何责任。

发表留言

全部留言 (0)

暂无留言,成为第一个留言的人吧!