feat: dplayer
This commit is contained in:
75
proxy.js
75
proxy.js
@@ -8,6 +8,8 @@ const port = 3000;
|
||||
// 允许跨域请求
|
||||
app.use((req, res, next) => {
|
||||
res.header('Access-Control-Allow-Origin', '*');
|
||||
res.header('Access-Control-Allow-Methods', 'GET, HEAD, OPTIONS');
|
||||
res.header('Access-Control-Allow-Headers', 'Range');
|
||||
next();
|
||||
});
|
||||
|
||||
@@ -18,22 +20,35 @@ app.get('/proxy', async (req, res) => {
|
||||
const targetUrl = req.query.url;
|
||||
console.log('Fetching data from:', targetUrl);
|
||||
if (!targetUrl) {
|
||||
return res.status(400).send('URL parameter is required');
|
||||
return res.status(400).json({ error: 'URL parameter is required' });
|
||||
}
|
||||
|
||||
try {
|
||||
// 设置请求头
|
||||
const headers = {};
|
||||
const headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
|
||||
};
|
||||
if (req.headers.range) {
|
||||
headers['Range'] = req.headers.range; // 转发 Range 请求头
|
||||
headers['Range'] = req.headers.range; // 转发 Range 请求头,支持视频分段加载
|
||||
}
|
||||
|
||||
// 向目标 URL 发起请求
|
||||
const response = await fetch(targetUrl, { headers });
|
||||
|
||||
// 检查响应状态
|
||||
if (!response.ok) {
|
||||
return res.status(response.status).json({
|
||||
error: `Failed to fetch: ${response.statusText}`,
|
||||
status: response.status
|
||||
});
|
||||
}
|
||||
|
||||
// 设置响应头
|
||||
response.headers.forEach((value, key) => {
|
||||
if (key !== 'content-encoding') { // 避免某些头信息导致问题
|
||||
// 跳过一些可能导致问题的头信息
|
||||
if (key.toLowerCase() !== 'content-encoding' &&
|
||||
key.toLowerCase() !== 'transfer-encoding' &&
|
||||
key.toLowerCase() !== 'connection') {
|
||||
res.setHeader(key, value);
|
||||
}
|
||||
});
|
||||
@@ -44,19 +59,55 @@ app.get('/proxy', async (req, res) => {
|
||||
}
|
||||
|
||||
// 将响应体直接流式传输给客户端
|
||||
response.body.pipe(res, { end: true });
|
||||
if (response.body) {
|
||||
response.body.pipe(res, { end: true });
|
||||
|
||||
// 错误处理
|
||||
response.body.on('error', (err) => {
|
||||
console.error('Error during data transfer:', err);
|
||||
res.status(500).send('Error during data transfer');
|
||||
});
|
||||
// 错误处理
|
||||
response.body.on('error', (err) => {
|
||||
console.error('Error during data transfer:', err);
|
||||
if (!res.headersSent) {
|
||||
res.status(500).json({ error: 'Error during data transfer' });
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.status(500).json({ error: 'No response body' });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error);
|
||||
res.status(500).send('Error fetching data');
|
||||
|
||||
// 根据错误类型返回更具体的错误信息
|
||||
let errorMessage = 'Error fetching data';
|
||||
let statusCode = 500;
|
||||
let hostname = '';
|
||||
|
||||
try {
|
||||
hostname = new URL(targetUrl).hostname;
|
||||
} catch (e) {
|
||||
hostname = 'unknown';
|
||||
}
|
||||
|
||||
if (error.code === 'ENOTFOUND') {
|
||||
errorMessage = `DNS解析失败:无法解析域名 "${hostname}"。请检查URL是否正确,或网络连接是否正常。`;
|
||||
statusCode = 502;
|
||||
} else if (error.code === 'ECONNREFUSED') {
|
||||
errorMessage = `连接被拒绝:无法连接到目标服务器 "${hostname}"。`;
|
||||
statusCode = 502;
|
||||
} else if (error.code === 'ETIMEDOUT') {
|
||||
errorMessage = `请求超时:目标服务器 "${hostname}" 响应时间过长。`;
|
||||
statusCode = 504;
|
||||
}
|
||||
|
||||
if (!res.headersSent) {
|
||||
res.status(statusCode).json({
|
||||
error: errorMessage,
|
||||
code: error.code,
|
||||
targetUrl: targetUrl
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Proxy server running at http://localhost:${port}`);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user