mirror of
https://github.com/handsomezhuzhu/AeroStart.git
synced 2026-02-20 12:00:15 +00:00
- Create api/bilibili.ts to handle Bilibili API requests in production - Proxy requests to https://s.search.bilibili.com/main/suggest - Add proper headers (User-Agent, Referer) to avoid blocking - Set CORS headers and cache control (60s) - Handle errors gracefully with fallback response - Update src/utils/suggestions.ts to detect environment - Use /bilibili (Vite proxy) in development - Use /api/bilibili (Vercel Function) in production - Check import.meta.env.DEV to determine environment This fixes the 404 error in production where Vite proxy is not available. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
85 lines
2.2 KiB
TypeScript
85 lines
2.2 KiB
TypeScript
import {
|
|
getSearchEngineConfig,
|
|
buildJsonpUrl,
|
|
type SearchEngineType
|
|
} from '@/config/searchEngines';
|
|
|
|
let callbackCount = 0;
|
|
|
|
/**
|
|
* Fetch search suggestions (supports hybrid JSONP and Fetch mode)
|
|
*/
|
|
export const fetchSuggestions = (engine: string, query: string): Promise<string[]> => {
|
|
return new Promise((resolve) => {
|
|
if (!query || !query.trim()) {
|
|
resolve([]);
|
|
return;
|
|
}
|
|
|
|
const config = getSearchEngineConfig(engine as SearchEngineType);
|
|
if (!config) {
|
|
resolve([]);
|
|
return;
|
|
}
|
|
|
|
// Bilibili uses fetch (via Vite proxy in dev, Vercel Function in production)
|
|
if (engine === 'Bilibili') {
|
|
// In production (Vercel), use /api/bilibili; in development, use /bilibili (Vite proxy)
|
|
const isDev = import.meta.env.DEV;
|
|
const url = isDev
|
|
? `/bilibili?term=${encodeURIComponent(query)}`
|
|
: `/api/bilibili?term=${encodeURIComponent(query)}`;
|
|
|
|
fetch(url)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
try {
|
|
const suggestions = config.parseResponse(data);
|
|
resolve(suggestions);
|
|
} catch (e) {
|
|
resolve([]);
|
|
}
|
|
})
|
|
.catch(() => {
|
|
resolve([]);
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Other engines use JSONP
|
|
const callbackName = `jsonp_cb_${Date.now()}_${callbackCount++}`;
|
|
const script = document.createElement('script');
|
|
let timeoutId: any;
|
|
|
|
const cleanup = () => {
|
|
if ((window as any)[callbackName]) delete (window as any)[callbackName];
|
|
if (document.body.contains(script)) document.body.removeChild(script);
|
|
if (timeoutId) clearTimeout(timeoutId);
|
|
};
|
|
|
|
// 3 seconds timeout
|
|
timeoutId = setTimeout(() => {
|
|
cleanup();
|
|
resolve([]);
|
|
}, 3000);
|
|
|
|
// Set global callback function
|
|
(window as any)[callbackName] = (data: any) => {
|
|
cleanup();
|
|
try {
|
|
const suggestions = config.parseResponse(data);
|
|
resolve(suggestions);
|
|
} catch (e) {
|
|
resolve([]);
|
|
}
|
|
};
|
|
|
|
// Build URL and make request
|
|
script.src = buildJsonpUrl(config, query, callbackName);
|
|
script.onerror = () => {
|
|
cleanup();
|
|
resolve([]);
|
|
};
|
|
document.body.appendChild(script);
|
|
});
|
|
}; |