支持动图下载和预览
This commit is contained in:
@@ -307,4 +307,41 @@ router.get('/:id/related', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
/**
|
||||
* 获取Ugoira动画的ZIP文件URL
|
||||
* GET /api/artwork/:id/ugoira
|
||||
*/
|
||||
router.get('/:id/ugoira', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
if (!id || isNaN(parseInt(id))) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Invalid artwork ID'
|
||||
});
|
||||
}
|
||||
|
||||
const artworkService = new ArtworkService(req.backend.getAuth());
|
||||
const result = await artworkService.getUgoiraZipUrl(parseInt(id));
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
+46
-2
@@ -3,6 +3,7 @@ const router = express.Router();
|
||||
const ImageCacheService = require('../services/image-cache');
|
||||
const ApiCacheService = require('../services/api-cache');
|
||||
const { defaultLogger } = require('../utils/logger');
|
||||
const axios = require('axios');
|
||||
|
||||
// 创建logger实例
|
||||
const logger = defaultLogger.child('ProxyRouter');
|
||||
@@ -53,6 +54,46 @@ router.get('/image', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 通用文件代理(支持ZIP等二进制资源)
|
||||
* GET /api/proxy/file?url=<encoded>
|
||||
*/
|
||||
router.get('/file', async (req, res) => {
|
||||
try {
|
||||
const { url } = req.query;
|
||||
if (!url) {
|
||||
return res.status(400).json({ success: false, error: 'File URL is required' });
|
||||
}
|
||||
|
||||
const decodedUrl = decodeURIComponent(url);
|
||||
|
||||
// 发起请求到源站(例如 i.pximg.net),设置必要头以通过防盗链
|
||||
const response = await axios.get(decodedUrl, {
|
||||
responseType: 'arraybuffer',
|
||||
headers: {
|
||||
Referer: 'https://www.pixiv.net/',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
|
||||
Accept: '*/*'
|
||||
},
|
||||
timeout: 60000
|
||||
});
|
||||
|
||||
const contentType = getContentType(decodedUrl);
|
||||
res.set({
|
||||
'Content-Type': contentType,
|
||||
'Cache-Control': 'public, max-age=600',
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'GET',
|
||||
'Access-Control-Allow-Headers': 'Content-Type'
|
||||
});
|
||||
|
||||
res.send(response.data);
|
||||
} catch (error) {
|
||||
logger.error('File proxy error:', { message: error.message, status: error.response?.status });
|
||||
res.status(500).json({ success: false, error: 'Failed to proxy file' });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 缓存管理 - 获取缓存统计信息
|
||||
* GET /api/proxy/cache/stats
|
||||
@@ -301,10 +342,13 @@ function getContentType(url) {
|
||||
'gif': 'image/gif',
|
||||
'webp': 'image/webp',
|
||||
'bmp': 'image/bmp',
|
||||
'svg': 'image/svg+xml'
|
||||
'svg': 'image/svg+xml',
|
||||
'zip': 'application/zip',
|
||||
'mp4': 'video/mp4',
|
||||
'webm': 'video/webm'
|
||||
};
|
||||
|
||||
return contentTypeMap[ext] || 'image/jpeg';
|
||||
}
|
||||
|
||||
module.exports = router;
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user