From 465e1f774648ecdbc6014fec9988f5fa417e724d Mon Sep 17 00:00:00 2001 From: wxs Date: Fri, 13 Mar 2026 21:04:53 +0800 Subject: [PATCH] =?UTF-8?q?fix(pugongying):=20=E4=BD=BF=E7=94=A8=20GM=5Fxm?= =?UTF-8?q?lhttpRequest=20=E8=A7=A3=E5=86=B3=E8=B7=A8=E5=9F=9F=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=20CORS=20=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 对代理 API 请求改用 GM_xmlhttpRequest 绕过浏览器 CORS 限制, 蒲公英官方 API 仍使用原生 fetch(同源无需跨域)。 Co-Authored-By: Claude Opus 4.6 --- pugongying/xhs-pgy-export.user.js | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/pugongying/xhs-pgy-export.user.js b/pugongying/xhs-pgy-export.user.js index a54f3d2..8eb29d8 100644 --- a/pugongying/xhs-pgy-export.user.js +++ b/pugongying/xhs-pgy-export.user.js @@ -4,7 +4,8 @@ // @version 0.1.1 // @description 输入达人主页链接或达人 ID,勾选字段后导出 Excel // @match https://pgy.xiaohongshu.com/* -// @grant none +// @grant GM_xmlhttpRequest +// @connect api.internal.intelligrow.cn // @require https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js // ==/UserScript== @@ -14,6 +15,27 @@ module.exports = api; } })(typeof globalThis !== "undefined" ? globalThis : this, function factory(root) { + function gmFetch(url, options) { + return new Promise((resolve, reject) => { + const headers = options && options.headers ? options.headers : {}; + GM_xmlhttpRequest({ + method: (options && options.method) || "GET", + url, + headers, + onload(res) { + resolve({ + ok: res.status >= 200 && res.status < 300, + status: res.status, + json: () => Promise.resolve(JSON.parse(res.responseText)), + }); + }, + onerror(err) { + reject(new Error("GM_xmlhttpRequest 网络错误: " + (err.statusText || url))); + }, + }); + }); + } + const API_BASE = "https://pgy.xiaohongshu.com/api/solar/cooperator/user/blogger/"; const PROXY_API_BASE = "https://api.internal.intelligrow.cn"; @@ -395,7 +417,9 @@ async function fetchSupplementalPayload(userId, fetchImpl, config) { const extra = typeof config.extraHeaders === "function" ? config.extraHeaders() : {}; - const response = await fetchImpl(config.buildUrl(userId), { + const hasExtra = Object.keys(extra).length > 0; + const fetcher = hasExtra && typeof GM_xmlhttpRequest === "function" ? gmFetch : fetchImpl; + const response = await fetcher(config.buildUrl(userId), { method: "GET", credentials: "include", headers: {