Next.js应用从Azure Blob存储下载Word文件损坏问题求助
解决Azure Blob下载Word文件后无法打开的问题
你遇到的核心问题是下载后的Word文件损坏,无法被MS Word正常识别,即使调整了Content-Type也未解决。以下是针对性的修复方案:
问题分析
- API层直接返回可读流(
readableStreamBody)可能导致数据传输不完整或格式异常,Next.js API路由对原始流的处理存在兼容性问题 - 前端重复包装Blob对象,可能破坏了原始文件的二进制结构
修复步骤
1. 修改API路由代码(转换流为Buffer)
将Azure Blob返回的可读流转换为Buffer后再返回,确保数据完整传递:
import { dataFound, dataNotFound } from '@/helpers/api-result'; import { BlobServiceClient } from '@azure/storage-blob'; import { Readable } from 'stream'; export const GET = async (request: any) => { try { const url = new URL(request.url); const fileName = url.searchParams.get('fileName') as string; const connectionString = process.env.NEXT_PUBLIC_AZURE_BLOB_STORAGE_CONNECTION_STRING; const containerName = "xxxxxxxx"; const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString!); const containerClient = blobServiceClient.getContainerClient(containerName); const blobClient = containerClient.getBlobClient(fileName); const blobDownloadResponse = await blobClient.download(); // 将可读流转换为Buffer,确保数据完整性 const stream = blobDownloadResponse.readableStreamBody as Readable; const chunks: Uint8Array[] = []; for await (const chunk of stream) { chunks.push(chunk); } const buffer = Buffer.concat(chunks); const headers = { 'Content-Disposition': `attachment; filename="${fileName}"`, 'Content-Type': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }; return dataFound({ status: 200, headers, body: buffer }); } catch (error) { return { status: 500, body: 'An error occurred while downloading the file.' }; } }
2. 简化前端下载代码
axios已指定responseType: "blob",返回的data.data已是合法Blob对象,无需重复包装:
const data = await axios.get("/api/download", { params: { fileName: originalFileName }, // 移除未使用的attachmentPath参数 responseType: "blob", }); if (data.status === 200) { const blobUrl = URL.createObjectURL(data.data); const a = document.createElement('a'); a.href = blobUrl; a.download = originalFileName; a.click(); URL.revokeObjectURL(blobUrl); }
额外检查项
- 确认Azure Blob存储中的原始Word文件可正常打开,排除上传阶段的损坏问题
- 检查文件名是否包含特殊字符,若有可尝试在
Content-Disposition中使用filename*=UTF-8''${encodeURIComponent(fileName)}编码格式
内容的提问来源于stack exchange,提问作者Ponmani Chinnaswamy
相关产品推荐
相关产品推荐

