// 猫眼票房排行榜 - JavaScript 实现
const API = {
endpoints: [],
currentIndex: 0,
params: {
encoding: 'json'
},
localFallback: '返回接口.json',
// 初始化API接口列表
async init() {
try {
const res = await fetch('./接口集合.json');
const endpoints = await res.json();
this.endpoints = endpoints.map(endpoint => `${endpoint}/v2/maoyan`);
} catch (e) {
// 如果无法加载接口集合,使用默认接口
this.endpoints = ['https://60s.api.shumengya.top/v2/maoyan'];
}
},
// 获取当前接口URL
getCurrentUrl() {
if (this.endpoints.length === 0) return null;
const url = new URL(this.endpoints[this.currentIndex]);
Object.entries(this.params).forEach(([k, v]) => url.searchParams.append(k, v));
return url.toString();
},
// 切换到下一个接口
switchToNext() {
this.currentIndex = (this.currentIndex + 1) % this.endpoints.length;
return this.currentIndex < this.endpoints.length;
},
// 重置到第一个接口
reset() {
this.currentIndex = 0;
}
};
let elements = {};
// 初始化
window.addEventListener('DOMContentLoaded', () => {
initElements();
loadMaoyanList();
});
function initElements() {
elements = {
container: document.getElementById('ranking-content'),
loading: document.getElementById('loading'),
updateTime: document.getElementById('api-update-time'),
statsTotal: document.getElementById('stats-total'),
statsTop10: document.getElementById('stats-top10')
};
}
async function loadMaoyanList() {
try {
showLoading(true);
// 优先从线上API请求
let data = await fetchFromAPI();
// 如果线上失败,尝试从本地返回接口.json加载
if (!data) {
data = await fetchFromLocal();
}
if (!data || data.code !== 200 || !data.data) {
throw new Error(data && data.message ? data.message : '未能获取到有效数据');
}
renderRanking(data.data);
} catch (error) {
console.error('加载排行榜失败:', error);
showError(error.message || '加载失败,请稍后重试');
} finally {
showLoading(false);
}
}
async function fetchFromAPI() {
// 初始化API接口列表
await API.init();
// 重置API索引到第一个接口
API.reset();
// 尝试所有API接口
for (let i = 0; i < API.endpoints.length; i++) {
try {
const url = API.getCurrentUrl();
console.log(`尝试接口 ${i + 1}/${API.endpoints.length}: ${url}`);
const resp = await fetch(url, {
cache: 'no-store',
timeout: 10000 // 10秒超时
});
if (!resp.ok) {
throw new Error(`HTTP ${resp.status}: ${resp.statusText}`);
}
const data = await resp.json();
if (data && data.code === 200) {
console.log(`接口 ${i + 1} 请求成功`);
return data;
}
throw new Error(data && data.message ? data.message : '接口返回异常');
} catch (e) {
console.warn(`接口 ${i + 1} 失败:`, e.message);
// 如果不是最后一个接口,切换到下一个
if (i < API.endpoints.length - 1) {
API.switchToNext();
continue;
}
// 所有接口都失败了
console.warn('所有远程接口都失败,尝试本地数据');
return null;
}
}
}
async function fetchFromLocal() {
try {
const resp = await fetch(API.localFallback + `?t=${Date.now()}`);
if (!resp.ok) throw new Error(`本地文件HTTP ${resp.status}`);
const data = await resp.json();
return data;
} catch (e) {
console.error('读取本地返回接口.json失败:', e);
return null;
}
}
function renderRanking(payload) {
const { list = [], tip = '', update_time = '', update_time_at } = payload || {};
// 更新时间
if (elements.updateTime) {
elements.updateTime.textContent = update_time ? `更新时间:${update_time}` : '';
}
// 统计信息
if (elements.statsTotal) {
elements.statsTotal.textContent = list.length;
}
if (elements.statsTop10) {
elements.statsTop10.textContent = Math.min(10, list.length);
}
// 渲染列表
const html = `
全球电影总票房排行榜
${escapeHtml(message)}
请稍后重试