个人主页V2.0
要实现真正的实时抓取,并且彻底解决 "RSS feed not found" 或 "Network Error" 的问题,通常是因为 rss2json 这个公共服务被您的服务器防火墙拦截了,或者它抓取超时。
为了绕过这个限制,我为您开发了 V29.0 强力穿透版。
核心技术升级:
-
更换抓取通道:弃用
rss2json,改用AllOrigins高速代理通道。它的穿透能力更强,能直接拿到您网站的原始数据。 -
浏览器端解析:不在云端转换,而是把数据拿回来后,直接用浏览器内置的 XML 解析器 (DOMParser) 处理。这就像浏览器直接访问您的 RSS 一样原生。
-
强制刷新机制:加入了毫秒级的时间戳,防止 CDN 或浏览器缓存旧文章。
请复制完整代码覆盖(这是纯 HTML 方案,无需修改服务器):
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Engr. Deng | HZPM</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=Playfair+Display:ital,wght@0,600;1,600&display=swap" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<style>
/* --- 基础设置 --- */
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
/* --- 极简背景 --- */
body {
margin: 0; padding: 0; min-height: 100vh;
font-family: 'Inter', sans-serif;
background-color: #f8fafc;
background-image:
radial-gradient(at 0% 0%, hsla(210, 40%, 96%, 1) 0, transparent 50%),
radial-gradient(at 100% 100%, hsla(220, 40%, 96%, 1) 0, transparent 50%);
color: #333;
display: flex; justify-content: center; align-items: center;
}
/* --- 卡片容器 --- */
.glass-card {
display: flex; width: 100%; max-width: 850px; height: 500px;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 1);
box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.1);
border-radius: 24px; position: relative; overflow: hidden; z-index: 1;
}
/* --- 活力橙折角 (无错位) --- */
.corner-bookmark-container {
position: absolute; top: 0; right: 0; z-index: 999;
transform-origin: top right;
transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
filter: drop-shadow(-3px 3px 5px rgba(234, 88, 12, 0.3));
cursor: pointer; text-decoration: none;
}
.corner-bookmark-container:hover { transform: scale(1.15); }
.corner-bookmark {
width: 0; height: 0;
border-top: 75px solid #ea580c;
border-left: 75px solid transparent;
}
.corner-icon {
position: absolute; top: 15px; right: 15px;
color: #fff; font-size: 16px; pointer-events: none;
}
/* 布局 */
.left-col { flex: 1.3; position: relative; background: #000; overflow: hidden; }
.bg-img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.7s ease; opacity: 0.95; }
.glass-card:hover .bg-img { transform: scale(1.05); }
.txt-overlay { position: absolute; bottom: 0; left: 0; width: 100%; padding: 40px 30px; background: linear-gradient(to top, rgba(0,0,0,0.8), transparent); color: white; z-index: 2; }
.right-col { flex: 1.7; padding: 30px 50px 20px 50px; display: flex; flex-direction: column; overflow-y: auto; position: relative; }
/* 文字 */
.en-font { font-family: 'Playfair Display', serif; font-size: 36px; font-weight: 600; font-style: italic; line-height: 1.1; margin-bottom: 5px; }
.cn-font { font-size: 14px; font-weight: 300; opacity: 0.9; letter-spacing: 2px; text-transform: uppercase; }
.tag { display: inline-block; font-size: 11px; font-weight: 600; letter-spacing: 1.5px; color: #64748b; background: #f1f5f9; padding: 8px 14px; border-radius: 4px; text-transform: uppercase; margin-bottom: 20px; }
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; margin-bottom: 15px; }
.sep { width: 100%; height: 1px; background: #e2e8f0; margin: 5px 0 15px 0; }
.head { font-family: 'Playfair Display', serif; font-size: 20px; color: #0f172a; margin-bottom: 15px; display: flex; justify-content: space-between; align-items: center; }
.refresh-btn { background: none; border: none; cursor: pointer; padding: 5px; margin-left: 8px; color: #94a3b8; font-size: 14px; transition: all 0.3s ease; }
.refresh-btn:hover { color: #ea580c; transform: rotate(180deg); }
.spin { animation: spin 1s linear infinite; color: #ea580c; pointer-events: none; }
@keyframes spin { 100% { transform: rotate(360deg); } }
.link { text-decoration: none; color: #1e293b; display: flex; flex-direction: column; gap: 4px; }
.lbl { font-size: 10px; color: #94a3b8; text-transform: uppercase; font-weight: 700; letter-spacing: 0.5px; display: flex; align-items: center; gap: 6px; }
.lbl i { font-size: 11px; color: #2563eb; }
.val { font-size: 13px; font-weight: 400; }
/* 状态条 */
#status-msg { font-size: 10px; color: #94a3b8; text-align: right; margin-top: 10px; opacity: 0.8; }
@media (max-width: 768px) {
body { display: block !important; padding: 15px !important; height: auto !important; }
.glass-card { display: block !important; height: auto !important; max-height: none !important; background: #ffffff !important; border-radius: 16px; margin-bottom: 50px; box-shadow: 0 5px 20px rgba(0,0,0,0.05); position: relative !important; z-index: 1 !important; }
.left-col { height: 260px !important; width: 100% !important; }
.right-col { padding: 30px 20px !important; height: auto !important; width: 100% !important; display: block !important; }
.grid { grid-template-columns: 1fr !important; gap: 20px !important; margin-bottom: 25px !important; }
.en-font { font-size: 32px !important; }
.tag { background: #eee !important; color: #333 !important; }
.link, .val { color: #111 !important; }
}
</style>
</head>
<body>
<div class="glass-card">
<a href="https://www.hzpm.com" target="_blank" class="corner-bookmark-container" title="Visit HZPM">
<div class="corner-bookmark"></div>
<i class="fas fa-external-link-alt corner-icon"></i>
</a>
<div class="left-col">
<img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="Profile" class="bg-img">
<div class="txt-overlay">
<div class="en-font">Engr. Deng</div>
<div class="cn-font">PM Expert @ HZPM</div>
</div>
</div>
<div class="right-col">
<div class="tag">HZPM / Portfolio</div>
<div class="grid">
<a href="#" class="link" style="pointer-events: none;">
<span class="lbl"><i class="fas fa-briefcase"></i> Position</span>
<span class="val">Supervisor</span>
</a>
<a href="mailto:hi@hzpm.com" class="link">
<span class="lbl"><i class="fas fa-envelope"></i> Email</span>
<span class="val">hi@hzpm.com</span>
</a>
<a href="https://www.hzpm.com" target="_blank" class="link">
<span class="lbl"><i class="fas fa-globe"></i> Website</span>
<span class="val">hzpm.com</span>
</a>
<a href="#" class="link" style="pointer-events: none;">
<span class="lbl"><i class="fas fa-location-dot"></i> City</span>
<span class="val">Shenzhen</span>
</a>
</div>
<div class="sep"></div>
<div class="head">
<div style="display: flex; align-items: center;">
<span style="color:#000;">Latest Updates</span>
<button class="refresh-btn" onclick="fetchRSS(true)" title="Force Refresh">
<i id="refresh-icon" class="fas fa-sync-alt"></i>
</button>
</div>
<a href="https://www.hzpm.com" style="font-size:11px; color:#999; text-decoration:none;">View All</a>
</div>
<div id="article-list" style="display: block; width: 100%;">
<div class="article-item" style="display:flex; position:relative; padding-bottom: 20px;">
<div style="position:absolute; left: 4px; top: 8px; bottom: 0; width: 1px; background: #e2e8f0;"></div>
<div style="width: 9px; height: 9px; background: #ccc; border-radius: 50%; z-index: 1; flex-shrink: 0; margin-top: 6px; box-shadow: 0 0 0 3px #f3f4f6;"></div>
<div style="padding-left: 15px;">
<a href="https://www.hzpm.com" target="_blank" style="text-decoration: none; display: block;">
<div style="font-size: 13px; color: #999; line-height: 1.4; font-weight: 500;">Loading latest articles...</div>
</a>
</div>
</div>
</div>
<div id="status-msg"></div>
</div>
</div>
<script>
// === 配置区 ===
// 请确保这个地址在浏览器里能直接打开并看到 XML 代码
const RSS_URL = 'https://www.hzpm.com/rss.php';
async function fetchRSS(isManual = false) {
const container = document.getElementById('article-list');
const icon = document.getElementById('refresh-icon');
const statusMsg = document.getElementById('status-msg');
icon.classList.add('spin');
if(isManual) statusMsg.innerText = "Connecting...";
try {
// 使用 AllOrigins 代理,它比 rss2json 更强大,能绕过更多限制
const proxyUrl = `https://api.allorigins.win/get?url=${encodeURIComponent(RSS_URL + '?t=' + Date.now())}`;
const response = await fetch(proxyUrl);
const data = await response.json();
if (!data.contents) throw new Error("Empty response");
// 使用浏览器内置解析器解析 XML
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(data.contents, "text/xml");
const items = xmlDoc.querySelectorAll("item");
if (items.length > 0) {
let html = '';
// 取前 6 条
for (let i = 0; i < Math.min(items.length, 6); i++) {
const item = items[i];
// 兼容不同 RSS 格式 (RSS 2.0 / Atom)
const title = item.querySelector("title") ? item.querySelector("title").textContent : "No Title";
const link = item.querySelector("link") ? item.querySelector("link").textContent : "#";
const isLast = i === Math.min(items.length, 6) - 1;
const lineHtml = isLast ? '' : '<div style="position:absolute; left: 4px; top: 8px; bottom: 0; width: 1px; background: #e2e8f0;"></div>';
const paddingHtml = isLast ? '' : 'padding-bottom: 20px;';
html += `
<div style="display:flex; position:relative; ${paddingHtml}">
${lineHtml}
<div style="width: 9px; height: 9px; background: #2563eb; border-radius: 50%; z-index: 1; flex-shrink: 0; margin-top: 6px; box-shadow: 0 0 0 3px #eff6ff;"></div>
<div style="padding-left: 15px;">
<a href="${link}" target="_blank" style="text-decoration: none; display: block;">
<div style="font-size: 13px; color: #333; line-height: 1.4; font-weight: 500;">${title}</div>
</a>
</div>
</div>`;
}
container.innerHTML = html;
statusMsg.innerText = "Live Synced via Proxy";
statusMsg.style.color = "#22c55e";
} else {
throw new Error("No items found in RSS");
}
} catch (error) {
console.error(error);
// 失败回退到静态数据 (Backup)
renderStaticBackup();
statusMsg.innerText = "Fetch failed (Showing Backup)";
statusMsg.style.color = "#ef4444";
} finally {
icon.classList.remove('spin');
}
}
// 如果抓取失败,显示这组写死的数据
function renderStaticBackup() {
const container = document.getElementById('article-list');
const backupLinks = [
{ t: "HZPM Strategic Project Management Guide", l: "https://www.hzpm.com" },
{ t: "Digital Transformation in Engineering", l: "https://www.hzpm.com" },
{ t: "Agile Practices for Construction", l: "https://www.hzpm.com" },
{ t: "Risk Control Strategies 2026", l: "https://www.hzpm.com" },
{ t: "Cross-functional Team Leadership", l: "https://www.hzpm.com" },
{ t: "Shenzhen Urban Planning Updates", l: "https://www.hzpm.com" }
];
let html = '';
backupLinks.forEach((item, index) => {
const isLast = index === backupLinks.length - 1;
const lineHtml = isLast ? '' : '<div style="position:absolute; left: 4px; top: 8px; bottom: 0; width: 1px; background: #e2e8f0;"></div>';
const paddingHtml = isLast ? '' : 'padding-bottom: 20px;';
html += `
<div style="display:flex; position:relative; ${paddingHtml}">
${lineHtml}
<div style="width: 9px; height: 9px; background: #94a3b8; border-radius: 50%; z-index: 1; flex-shrink: 0; margin-top: 6px; box-shadow: 0 0 0 3px #f1f5f9;"></div>
<div style="padding-left: 15px;">
<a href="${item.l}" target="_blank" style="text-decoration: none; display: block;">
<div style="font-size: 13px; color: #64748b; line-height: 1.4; font-weight: 500;">${item.t}</div>
</a>
</div>
</div>`;
});
container.innerHTML = html;
}
document.addEventListener('DOMContentLoaded', () => fetchRSS(false));
</script>
</body>
</html>
扫描二维码,在手机上阅读
发表评论
