Files
JKVideo/dev-proxy.js
Developer 4d71f39ee9 fix: proxy B站图片 CDN 解决 web 端防盗链图片不显示问题
- dev-proxy.js 新增 /bilibili-img 路由,代理 *.hdslb.com 并注入正确 Referer
- utils/imageUrl.ts 新增 proxyImageUrl(),web 端将图片 URL 转为本地代理地址
- VideoCard / CommentItem / MiniPlayer / [bvid] 对所有 B站图片应用 proxyImageUrl
2026-03-10 20:47:14 +08:00

70 lines
2.5 KiB
JavaScript

const https = require('https');
const express = require('express');
const app = express();
// CORS: allow any local origin (Expo web dev server)
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-Buvid3, X-Sessdata');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
if (req.method === 'OPTIONS') return res.sendStatus(200);
next();
});
function makeProxy(targetHost) {
return (req, res) => {
const buvid3 = req.headers['x-buvid3'] || '';
const sessdata = req.headers['x-sessdata'] || '';
const cookies = [
buvid3 && `buvid3=${buvid3}`,
sessdata && `SESSDATA=${sessdata}`,
].filter(Boolean).join('; ');
const options = {
hostname: targetHost,
path: req.url,
method: req.method,
headers: {
'Cookie': cookies,
'Referer': 'https://www.bilibili.com',
'Origin': 'https://www.bilibili.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36',
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9',
},
};
const proxy = https.request(options, (proxyRes) => {
// On successful QR login, extract SESSDATA from set-cookie and relay via custom header
const setCookies = proxyRes.headers['set-cookie'] || [];
const match = setCookies.find(c => c.includes('SESSDATA='));
if (match) {
const val = match.split(';')[0].replace('SESSDATA=', '');
res.setHeader('X-Sessdata', val);
}
res.writeHead(proxyRes.statusCode, {
'Content-Type': proxyRes.headers['content-type'] || 'application/json',
});
proxyRes.pipe(res);
});
proxy.on('error', (err) => res.status(502).json({ error: err.message }));
req.pipe(proxy);
};
}
app.use('/bilibili-api', makeProxy('api.bilibili.com'));
app.use('/bilibili-passport', makeProxy('passport.bilibili.com'));
// Image CDN proxy — strips the host segment and forwards to the real CDN with Referer
app.use('/bilibili-img', (req, res) => {
const parts = req.url.split('/').filter(Boolean);
const host = parts[0];
if (!host || !host.endsWith('.hdslb.com')) return res.status(403).end();
req.url = '/' + parts.slice(1).join('/');
makeProxy(host)(req, res);
});
const PORT = process.env.PROXY_PORT || 3001;
app.listen(PORT, () => console.log(`[Proxy] http://localhost:${PORT}`));