豆瓣数据源增加备用源
This commit is contained in:
+244
-98
@@ -88,6 +88,36 @@ interface DoubanDetailApiResponse {
|
||||
[key: string]: any; // 允许其他字段
|
||||
}
|
||||
|
||||
type DoubanProxyType =
|
||||
| 'direct'
|
||||
| 'cors-proxy-zwei'
|
||||
| 'cmliussss-cdn-tencent'
|
||||
| 'cmliussss-cdn-ali'
|
||||
| 'cors-anywhere'
|
||||
| 'custom';
|
||||
|
||||
function normalizeDoubanProxyConfig(
|
||||
proxyType: DoubanProxyType,
|
||||
proxyUrl: string
|
||||
): {
|
||||
proxyType: DoubanProxyType;
|
||||
proxyUrl: string;
|
||||
} {
|
||||
const normalizedProxyUrl = proxyUrl.trim();
|
||||
|
||||
if (proxyType === 'custom' && !normalizedProxyUrl) {
|
||||
return {
|
||||
proxyType: 'direct',
|
||||
proxyUrl: '',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
proxyType,
|
||||
proxyUrl: normalizedProxyUrl,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 带超时的 fetch 请求
|
||||
*/
|
||||
@@ -135,6 +165,14 @@ function getDoubanProxyConfig(): {
|
||||
| 'cors-anywhere'
|
||||
| 'custom';
|
||||
proxyUrl: string;
|
||||
backupProxyType:
|
||||
| 'direct'
|
||||
| 'cors-proxy-zwei'
|
||||
| 'cmliussss-cdn-tencent'
|
||||
| 'cmliussss-cdn-ali'
|
||||
| 'cors-anywhere'
|
||||
| 'custom';
|
||||
backupProxyUrl: string;
|
||||
} {
|
||||
const doubanProxyType =
|
||||
localStorage.getItem('doubanDataSource') ||
|
||||
@@ -144,12 +182,115 @@ function getDoubanProxyConfig(): {
|
||||
localStorage.getItem('doubanProxyUrl') ||
|
||||
(window as any).RUNTIME_CONFIG?.DOUBAN_PROXY ||
|
||||
'';
|
||||
const doubanProxyBackupType =
|
||||
(localStorage.getItem('doubanDataSourceBackup') as DoubanProxyType | null) ||
|
||||
'direct';
|
||||
const doubanProxyBackupUrl =
|
||||
localStorage.getItem('doubanProxyUrlBackup') || '';
|
||||
const primaryConfig = normalizeDoubanProxyConfig(doubanProxyType, doubanProxy);
|
||||
const backupConfig = normalizeDoubanProxyConfig(
|
||||
doubanProxyBackupType,
|
||||
doubanProxyBackupUrl
|
||||
);
|
||||
return {
|
||||
proxyType: doubanProxyType,
|
||||
proxyUrl: doubanProxy,
|
||||
proxyType: primaryConfig.proxyType,
|
||||
proxyUrl: primaryConfig.proxyUrl,
|
||||
backupProxyType: backupConfig.proxyType,
|
||||
backupProxyUrl: backupConfig.proxyUrl,
|
||||
};
|
||||
}
|
||||
|
||||
function buildDoubanRequester(
|
||||
proxyType: DoubanProxyType,
|
||||
proxyUrl: string
|
||||
): {
|
||||
useDirectApi: boolean;
|
||||
requestProxyUrl: string;
|
||||
useTencentCDN: boolean;
|
||||
useAliCDN: boolean;
|
||||
} {
|
||||
switch (proxyType) {
|
||||
case 'cors-proxy-zwei':
|
||||
return {
|
||||
useDirectApi: false,
|
||||
requestProxyUrl: 'https://ciao-cors.is-an.org/',
|
||||
useTencentCDN: false,
|
||||
useAliCDN: false,
|
||||
};
|
||||
case 'cmliussss-cdn-tencent':
|
||||
return {
|
||||
useDirectApi: false,
|
||||
requestProxyUrl: '',
|
||||
useTencentCDN: true,
|
||||
useAliCDN: false,
|
||||
};
|
||||
case 'cmliussss-cdn-ali':
|
||||
return {
|
||||
useDirectApi: false,
|
||||
requestProxyUrl: '',
|
||||
useTencentCDN: false,
|
||||
useAliCDN: true,
|
||||
};
|
||||
case 'cors-anywhere':
|
||||
return {
|
||||
useDirectApi: false,
|
||||
requestProxyUrl: 'https://cors-anywhere.com/',
|
||||
useTencentCDN: false,
|
||||
useAliCDN: false,
|
||||
};
|
||||
case 'custom':
|
||||
return {
|
||||
useDirectApi: false,
|
||||
requestProxyUrl: proxyUrl,
|
||||
useTencentCDN: false,
|
||||
useAliCDN: false,
|
||||
};
|
||||
case 'direct':
|
||||
default:
|
||||
return {
|
||||
useDirectApi: true,
|
||||
requestProxyUrl: '',
|
||||
useTencentCDN: false,
|
||||
useAliCDN: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async function requestDoubanWithFallback<T>(
|
||||
primary: { proxyType: DoubanProxyType; proxyUrl: string },
|
||||
backup: { proxyType: DoubanProxyType; proxyUrl: string },
|
||||
runner: (requester: ReturnType<typeof buildDoubanRequester>) => Promise<T>
|
||||
): Promise<T> {
|
||||
const primaryRequester = buildDoubanRequester(primary.proxyType, primary.proxyUrl);
|
||||
const backupRequester = buildDoubanRequester(backup.proxyType, backup.proxyUrl);
|
||||
|
||||
try {
|
||||
return await runner(primaryRequester);
|
||||
} catch (primaryError) {
|
||||
const sameStrategy =
|
||||
primary.proxyType === backup.proxyType && primary.proxyUrl === backup.proxyUrl;
|
||||
if (sameStrategy) {
|
||||
throw primaryError;
|
||||
}
|
||||
|
||||
console.warn(
|
||||
`[Douban] 主渠道失败,切换备用渠道: ${primary.proxyType} -> ${backup.proxyType}`,
|
||||
primaryError
|
||||
);
|
||||
return runner(backupRequester);
|
||||
}
|
||||
}
|
||||
|
||||
function dispatchDoubanGlobalError(message: string) {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('globalError', {
|
||||
detail: { message },
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 浏览器端豆瓣分类数据获取函数
|
||||
*/
|
||||
@@ -211,14 +352,6 @@ export async function fetchDoubanCategories(
|
||||
list: list,
|
||||
};
|
||||
} catch (error) {
|
||||
// 触发全局错误提示
|
||||
if (typeof window !== 'undefined') {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('globalError', {
|
||||
detail: { message: '获取豆瓣分类数据失败' },
|
||||
})
|
||||
);
|
||||
}
|
||||
throw new Error(`获取豆瓣分类数据失败: ${(error as Error).message}`);
|
||||
}
|
||||
}
|
||||
@@ -230,25 +363,34 @@ export async function getDoubanCategories(
|
||||
params: DoubanCategoriesParams
|
||||
): Promise<DoubanResult> {
|
||||
const { kind, category, type, pageLimit = 20, pageStart = 0 } = params;
|
||||
const { proxyType, proxyUrl } = getDoubanProxyConfig();
|
||||
switch (proxyType) {
|
||||
case 'cors-proxy-zwei':
|
||||
return fetchDoubanCategories(params, 'https://ciao-cors.is-an.org/');
|
||||
case 'cmliussss-cdn-tencent':
|
||||
return fetchDoubanCategories(params, '', true, false);
|
||||
case 'cmliussss-cdn-ali':
|
||||
return fetchDoubanCategories(params, '', false, true);
|
||||
case 'cors-anywhere':
|
||||
return fetchDoubanCategories(params, 'https://cors-anywhere.com/');
|
||||
case 'custom':
|
||||
return fetchDoubanCategories(params, proxyUrl);
|
||||
case 'direct':
|
||||
default:
|
||||
const response = await fetch(
|
||||
`/api/douban/categories?kind=${kind}&category=${category}&type=${type}&limit=${pageLimit}&start=${pageStart}`
|
||||
);
|
||||
const { proxyType, proxyUrl, backupProxyType, backupProxyUrl } =
|
||||
getDoubanProxyConfig();
|
||||
try {
|
||||
return await requestDoubanWithFallback(
|
||||
{ proxyType, proxyUrl },
|
||||
{ proxyType: backupProxyType, proxyUrl: backupProxyUrl },
|
||||
async ({ useDirectApi, requestProxyUrl, useTencentCDN, useAliCDN }) => {
|
||||
if (useDirectApi) {
|
||||
const response = await fetch(
|
||||
`/api/douban/categories?kind=${kind}&category=${category}&type=${type}&limit=${pageLimit}&start=${pageStart}`
|
||||
);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
}
|
||||
return response.json();
|
||||
}
|
||||
|
||||
return response.json();
|
||||
return fetchDoubanCategories(
|
||||
params,
|
||||
requestProxyUrl,
|
||||
useTencentCDN,
|
||||
useAliCDN
|
||||
);
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
dispatchDoubanGlobalError('获取豆瓣分类数据失败');
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,25 +405,34 @@ export async function getDoubanList(
|
||||
params: DoubanListParams
|
||||
): Promise<DoubanResult> {
|
||||
const { tag, type, pageLimit = 20, pageStart = 0 } = params;
|
||||
const { proxyType, proxyUrl } = getDoubanProxyConfig();
|
||||
switch (proxyType) {
|
||||
case 'cors-proxy-zwei':
|
||||
return fetchDoubanList(params, 'https://ciao-cors.is-an.org/');
|
||||
case 'cmliussss-cdn-tencent':
|
||||
return fetchDoubanList(params, '', true, false);
|
||||
case 'cmliussss-cdn-ali':
|
||||
return fetchDoubanList(params, '', false, true);
|
||||
case 'cors-anywhere':
|
||||
return fetchDoubanList(params, 'https://cors-anywhere.com/');
|
||||
case 'custom':
|
||||
return fetchDoubanList(params, proxyUrl);
|
||||
case 'direct':
|
||||
default:
|
||||
const response = await fetch(
|
||||
`/api/douban?tag=${tag}&type=${type}&pageSize=${pageLimit}&pageStart=${pageStart}`
|
||||
);
|
||||
const { proxyType, proxyUrl, backupProxyType, backupProxyUrl } =
|
||||
getDoubanProxyConfig();
|
||||
try {
|
||||
return await requestDoubanWithFallback(
|
||||
{ proxyType, proxyUrl },
|
||||
{ proxyType: backupProxyType, proxyUrl: backupProxyUrl },
|
||||
async ({ useDirectApi, requestProxyUrl, useTencentCDN, useAliCDN }) => {
|
||||
if (useDirectApi) {
|
||||
const response = await fetch(
|
||||
`/api/douban?tag=${tag}&type=${type}&pageSize=${pageLimit}&pageStart=${pageStart}`
|
||||
);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
}
|
||||
return response.json();
|
||||
}
|
||||
|
||||
return response.json();
|
||||
return fetchDoubanList(
|
||||
params,
|
||||
requestProxyUrl,
|
||||
useTencentCDN,
|
||||
useAliCDN
|
||||
);
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
dispatchDoubanGlobalError('获取豆瓣列表数据失败');
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,14 +494,6 @@ export async function fetchDoubanList(
|
||||
list: list,
|
||||
};
|
||||
} catch (error) {
|
||||
// 触发全局错误提示
|
||||
if (typeof window !== 'undefined') {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('globalError', {
|
||||
detail: { message: '获取豆瓣列表数据失败' },
|
||||
})
|
||||
);
|
||||
}
|
||||
throw new Error(`获取豆瓣分类数据失败: ${(error as Error).message}`);
|
||||
}
|
||||
}
|
||||
@@ -383,25 +526,34 @@ export async function getDoubanRecommends(
|
||||
platform,
|
||||
sort,
|
||||
} = params;
|
||||
const { proxyType, proxyUrl } = getDoubanProxyConfig();
|
||||
switch (proxyType) {
|
||||
case 'cors-proxy-zwei':
|
||||
return fetchDoubanRecommends(params, 'https://ciao-cors.is-an.org/');
|
||||
case 'cmliussss-cdn-tencent':
|
||||
return fetchDoubanRecommends(params, '', true, false);
|
||||
case 'cmliussss-cdn-ali':
|
||||
return fetchDoubanRecommends(params, '', false, true);
|
||||
case 'cors-anywhere':
|
||||
return fetchDoubanRecommends(params, 'https://cors-anywhere.com/');
|
||||
case 'custom':
|
||||
return fetchDoubanRecommends(params, proxyUrl);
|
||||
case 'direct':
|
||||
default:
|
||||
const response = await fetch(
|
||||
`/api/douban/recommends?kind=${kind}&limit=${pageLimit}&start=${pageStart}&category=${category}&format=${format}®ion=${region}&year=${year}&platform=${platform}&sort=${sort}&label=${label}`
|
||||
);
|
||||
const { proxyType, proxyUrl, backupProxyType, backupProxyUrl } =
|
||||
getDoubanProxyConfig();
|
||||
try {
|
||||
return await requestDoubanWithFallback(
|
||||
{ proxyType, proxyUrl },
|
||||
{ proxyType: backupProxyType, proxyUrl: backupProxyUrl },
|
||||
async ({ useDirectApi, requestProxyUrl, useTencentCDN, useAliCDN }) => {
|
||||
if (useDirectApi) {
|
||||
const response = await fetch(
|
||||
`/api/douban/recommends?kind=${kind}&limit=${pageLimit}&start=${pageStart}&category=${category}&format=${format}®ion=${region}&year=${year}&platform=${platform}&sort=${sort}&label=${label}`
|
||||
);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
}
|
||||
return response.json();
|
||||
}
|
||||
|
||||
return response.json();
|
||||
return fetchDoubanRecommends(
|
||||
params,
|
||||
requestProxyUrl,
|
||||
useTencentCDN,
|
||||
useAliCDN
|
||||
);
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
dispatchDoubanGlobalError('获取豆瓣推荐数据失败');
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,14 +696,6 @@ export async function fetchDoubanDetail(
|
||||
const doubanData: DoubanDetailApiResponse = await response.json();
|
||||
return doubanData;
|
||||
} catch (error) {
|
||||
// 触发全局错误提示
|
||||
if (typeof window !== 'undefined') {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('globalError', {
|
||||
detail: { message: '获取豆瓣详情数据失败' },
|
||||
})
|
||||
);
|
||||
}
|
||||
throw new Error(`获取豆瓣详情数据失败: ${(error as Error).message}`);
|
||||
}
|
||||
}
|
||||
@@ -562,24 +706,26 @@ export async function fetchDoubanDetail(
|
||||
export async function getDoubanDetail(
|
||||
id: string
|
||||
): Promise<DoubanDetailApiResponse> {
|
||||
const { proxyType, proxyUrl } = getDoubanProxyConfig();
|
||||
switch (proxyType) {
|
||||
case 'cors-proxy-zwei':
|
||||
return fetchDoubanDetail(id, 'https://ciao-cors.is-an.org/');
|
||||
case 'cmliussss-cdn-tencent':
|
||||
return fetchDoubanDetail(id, '', true, false);
|
||||
case 'cmliussss-cdn-ali':
|
||||
return fetchDoubanDetail(id, '', false, true);
|
||||
case 'cors-anywhere':
|
||||
return fetchDoubanDetail(id, 'https://cors-anywhere.com/');
|
||||
case 'custom':
|
||||
return fetchDoubanDetail(id, proxyUrl);
|
||||
case 'direct':
|
||||
default:
|
||||
const response = await fetch(`/api/douban/detail?id=${id}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
const { proxyType, proxyUrl, backupProxyType, backupProxyUrl } =
|
||||
getDoubanProxyConfig();
|
||||
try {
|
||||
return await requestDoubanWithFallback(
|
||||
{ proxyType, proxyUrl },
|
||||
{ proxyType: backupProxyType, proxyUrl: backupProxyUrl },
|
||||
async ({ useDirectApi, requestProxyUrl, useTencentCDN, useAliCDN }) => {
|
||||
if (useDirectApi) {
|
||||
const response = await fetch(`/api/douban/detail?id=${id}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
}
|
||||
return response.json();
|
||||
}
|
||||
|
||||
return fetchDoubanDetail(id, requestProxyUrl, useTencentCDN, useAliCDN);
|
||||
}
|
||||
return response.json();
|
||||
);
|
||||
} catch (error) {
|
||||
dispatchDoubanGlobalError('获取豆瓣详情数据失败');
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
+121
-28
@@ -3,8 +3,7 @@ import bs58 from 'bs58';
|
||||
import he from 'he';
|
||||
import Hls from 'hls.js';
|
||||
|
||||
function getDoubanImageProxyConfig(): {
|
||||
proxyType:
|
||||
export type DoubanImageProxyType =
|
||||
| 'direct'
|
||||
| 'server'
|
||||
| 'img3'
|
||||
@@ -12,13 +11,72 @@ function getDoubanImageProxyConfig(): {
|
||||
| 'cmliussss-cdn-ali'
|
||||
| 'baidu'
|
||||
| 'custom';
|
||||
|
||||
function normalizeDoubanImageProxyConfig(
|
||||
proxyType: DoubanImageProxyType,
|
||||
proxyUrl: string
|
||||
): {
|
||||
proxyType: DoubanImageProxyType;
|
||||
proxyUrl: string;
|
||||
} {
|
||||
const normalizedProxyUrl = proxyUrl.trim();
|
||||
|
||||
if (proxyType === 'custom' && !normalizedProxyUrl) {
|
||||
return {
|
||||
proxyType: 'server',
|
||||
proxyUrl: '',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
proxyType,
|
||||
proxyUrl: normalizedProxyUrl,
|
||||
};
|
||||
}
|
||||
|
||||
function buildDoubanImageUrl(
|
||||
originalUrl: string,
|
||||
proxyType: DoubanImageProxyType,
|
||||
proxyUrl: string
|
||||
): string {
|
||||
switch (proxyType) {
|
||||
case 'server':
|
||||
return `/api/image-proxy?url=${encodeURIComponent(originalUrl)}`;
|
||||
case 'img3':
|
||||
return originalUrl.replace(/img\d+\.doubanio\.com/g, 'img3.doubanio.com');
|
||||
case 'cmliussss-cdn-tencent':
|
||||
return originalUrl.replace(
|
||||
/img\d+\.doubanio\.com/g,
|
||||
'img.doubanio.cmliussss.net'
|
||||
);
|
||||
case 'cmliussss-cdn-ali':
|
||||
return originalUrl.replace(
|
||||
/img\d+\.doubanio\.com/g,
|
||||
'img.doubanio.cmliussss.com'
|
||||
);
|
||||
case 'baidu':
|
||||
return `https://image.baidu.com/search/down?url=${encodeURIComponent(originalUrl)}`;
|
||||
case 'custom':
|
||||
return proxyUrl ? `${proxyUrl}${encodeURIComponent(originalUrl)}` : originalUrl;
|
||||
case 'direct':
|
||||
default:
|
||||
return originalUrl;
|
||||
}
|
||||
}
|
||||
|
||||
function getDoubanImageProxyConfig(): {
|
||||
proxyType: DoubanImageProxyType;
|
||||
proxyUrl: string;
|
||||
backupProxyType: DoubanImageProxyType;
|
||||
backupProxyUrl: string;
|
||||
} {
|
||||
// 确保在浏览器环境中执行
|
||||
if (typeof window === 'undefined') {
|
||||
return {
|
||||
proxyType: 'cmliussss-cdn-tencent',
|
||||
proxyUrl: '',
|
||||
backupProxyType: 'server',
|
||||
backupProxyUrl: '',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -30,12 +88,70 @@ function getDoubanImageProxyConfig(): {
|
||||
localStorage.getItem('doubanImageProxyUrl') ||
|
||||
(window as any).RUNTIME_CONFIG?.DOUBAN_IMAGE_PROXY ||
|
||||
'';
|
||||
const doubanImageProxyBackupType =
|
||||
(localStorage.getItem('doubanImageProxyTypeBackup') as DoubanImageProxyType | null) ||
|
||||
'server';
|
||||
const doubanImageProxyBackupUrl =
|
||||
localStorage.getItem('doubanImageProxyUrlBackup') || '';
|
||||
const primaryConfig = normalizeDoubanImageProxyConfig(
|
||||
doubanImageProxyType,
|
||||
doubanImageProxy
|
||||
);
|
||||
const backupConfig = normalizeDoubanImageProxyConfig(
|
||||
doubanImageProxyBackupType,
|
||||
doubanImageProxyBackupUrl
|
||||
);
|
||||
return {
|
||||
proxyType: doubanImageProxyType,
|
||||
proxyUrl: doubanImageProxy,
|
||||
proxyType: primaryConfig.proxyType,
|
||||
proxyUrl: primaryConfig.proxyUrl,
|
||||
backupProxyType: backupConfig.proxyType,
|
||||
backupProxyUrl: backupConfig.proxyUrl,
|
||||
};
|
||||
}
|
||||
|
||||
export function getDoubanImageFallbackUrl(originalUrl: string): string | null {
|
||||
if (!originalUrl || !originalUrl.includes('doubanio.com')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { proxyType, proxyUrl, backupProxyType, backupProxyUrl } =
|
||||
getDoubanImageProxyConfig();
|
||||
const primaryUrl = buildDoubanImageUrl(originalUrl, proxyType, proxyUrl);
|
||||
const backupUrl = buildDoubanImageUrl(
|
||||
originalUrl,
|
||||
backupProxyType,
|
||||
backupProxyUrl
|
||||
);
|
||||
|
||||
if (backupUrl === primaryUrl) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return backupUrl;
|
||||
}
|
||||
|
||||
export function tryApplyDoubanImageFallback(
|
||||
target: HTMLImageElement,
|
||||
originalUrl: string
|
||||
): boolean {
|
||||
if (!originalUrl || !originalUrl.includes('doubanio.com')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target.dataset.doubanBackupTried === 'true') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const fallbackUrl = getDoubanImageFallbackUrl(originalUrl);
|
||||
if (!fallbackUrl || fallbackUrl === target.currentSrc || fallbackUrl === target.src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
target.dataset.doubanBackupTried = 'true';
|
||||
target.src = fallbackUrl;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理图片 URL,根据用户设置使用相应的代理
|
||||
*/
|
||||
@@ -65,29 +181,7 @@ export function processImageUrl(originalUrl: string): string {
|
||||
}
|
||||
|
||||
const { proxyType, proxyUrl } = getDoubanImageProxyConfig();
|
||||
switch (proxyType) {
|
||||
case 'server':
|
||||
return `/api/image-proxy?url=${encodeURIComponent(originalUrl)}`;
|
||||
case 'img3':
|
||||
return originalUrl.replace(/img\d+\.doubanio\.com/g, 'img3.doubanio.com');
|
||||
case 'cmliussss-cdn-tencent':
|
||||
return originalUrl.replace(
|
||||
/img\d+\.doubanio\.com/g,
|
||||
'img.doubanio.cmliussss.net'
|
||||
);
|
||||
case 'cmliussss-cdn-ali':
|
||||
return originalUrl.replace(
|
||||
/img\d+\.doubanio\.com/g,
|
||||
'img.doubanio.cmliussss.com'
|
||||
);
|
||||
case 'baidu':
|
||||
return `https://image.baidu.com/search/down?url=${encodeURIComponent(originalUrl)}`;
|
||||
case 'custom':
|
||||
return `${proxyUrl}${encodeURIComponent(originalUrl)}`;
|
||||
case 'direct':
|
||||
default:
|
||||
return originalUrl;
|
||||
}
|
||||
return buildDoubanImageUrl(originalUrl, proxyType, proxyUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -406,4 +500,3 @@ export function base58Decode(encoded: string): string {
|
||||
// 在 Node.js 环境中使用 Buffer
|
||||
return Buffer.from(bytes).toString('utf-8');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user