fix: use preview-mode signed URLs and graceful media preview fallback
This commit is contained in:
@@ -686,6 +686,30 @@ function getBusyDownloadMessage() {
|
||||
return '当前网络繁忙,请稍后再试';
|
||||
}
|
||||
|
||||
function getPreviewContentTypeByPath(filePath = '') {
|
||||
const ext = path.extname(String(filePath || '')).toLowerCase();
|
||||
const map = {
|
||||
'.jpg': 'image/jpeg',
|
||||
'.jpeg': 'image/jpeg',
|
||||
'.png': 'image/png',
|
||||
'.gif': 'image/gif',
|
||||
'.bmp': 'image/bmp',
|
||||
'.webp': 'image/webp',
|
||||
'.svg': 'image/svg+xml',
|
||||
'.mp4': 'video/mp4',
|
||||
'.mov': 'video/quicktime',
|
||||
'.webm': 'video/webm',
|
||||
'.mkv': 'video/x-matroska',
|
||||
'.mp3': 'audio/mpeg',
|
||||
'.wav': 'audio/wav',
|
||||
'.flac': 'audio/flac',
|
||||
'.ogg': 'audio/ogg',
|
||||
'.m4a': 'audio/mp4',
|
||||
'.aac': 'audio/aac'
|
||||
};
|
||||
return map[ext] || '';
|
||||
}
|
||||
|
||||
function parseDateTimeValue(value) {
|
||||
if (!value || typeof value !== 'string') {
|
||||
return null;
|
||||
@@ -4534,6 +4558,8 @@ app.post('/api/files/upload-complete', authMiddleware, async (req, res) => {
|
||||
// 生成 OSS 下载签名 URL(用户直连 OSS 下载,不经过后端)
|
||||
app.get('/api/files/download-url', authMiddleware, async (req, res) => {
|
||||
const filePath = req.query.path;
|
||||
const mode = String(req.query.mode || 'download').toLowerCase();
|
||||
const isPreviewMode = mode === 'preview';
|
||||
|
||||
if (!filePath) {
|
||||
return res.status(400).json({
|
||||
@@ -4610,12 +4636,22 @@ app.get('/api/files/download-url', authMiddleware, async (req, res) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 创建 GetObject 命令
|
||||
const command = new GetObjectCommand({
|
||||
// 创建 GetObject 命令(预览模式使用 inline,下载模式使用 attachment)
|
||||
const fileName = normalizedPath.split('/').pop() || 'download.bin';
|
||||
const commandInput = {
|
||||
Bucket: bucket,
|
||||
Key: objectKey,
|
||||
ResponseContentDisposition: `attachment; filename="${encodeURIComponent(normalizedPath.split('/').pop())}"`
|
||||
});
|
||||
ResponseContentDisposition: isPreviewMode
|
||||
? `inline; filename*=UTF-8''${encodeURIComponent(fileName)}`
|
||||
: `attachment; filename*=UTF-8''${encodeURIComponent(fileName)}`
|
||||
};
|
||||
if (isPreviewMode) {
|
||||
const previewContentType = getPreviewContentTypeByPath(fileName);
|
||||
if (previewContentType) {
|
||||
commandInput.ResponseContentType = previewContentType;
|
||||
}
|
||||
}
|
||||
const command = new GetObjectCommand(commandInput);
|
||||
|
||||
// 生成签名 URL(1小时有效)
|
||||
const signedUrl = await getSignedUrl(client, command, { expiresIn: 3600 });
|
||||
|
||||
Reference in New Issue
Block a user