如何下载前端接收的varbinary格式PDF二进制缓冲数据?
解决PDF二进制数据下载错误的方案
问题核心
后端从MSSQL取出的PDF是Buffer类型,直接传给EJS渲染时会被转换成原始PDF文本(而非Base64编码),但前端下载函数期望接收Base64格式数据,导致atob()解析失败,控制台输出原始PDF内容。
修复步骤
1. 后端将Buffer转换为Base64字符串
在查询数据库后,把additional_documents字段从Buffer转为Base64编码:
// 假设查询结果为result.recordset const processedDocuments = result.recordset.map(doc => ({ ...doc, // 仅当存在数据时转换,避免null报错 additional_documents: doc.additional_documents ? doc.additional_documents.toString('base64') : null })); // 传递给EJS视图 res.render('your-view-name', { documents: processedDocuments });
2. 修正EJS渲染代码
- 给文件名参数添加单引号(语法错误)
- 确保传递的是转换后的Base64字符串
<tr> <td><%= document.policy_number %> <br> <%= document.policy_type %></td> <td><%= document.status %></td> <td>UM/UIM <br> FORM</td> <td><% if (document.additional_documents !== null) { %> <a href="#" onclick="downloadFile('<%= document.additional_documents %>', 'test.pdf')">✅Additional Docs</a> <% } else { %> ❌No additional docs <% } %> <br> <%= document.endorsements !== null ? '✅Endorsements' : '❌No endorsements' %> <br> <%= document.proof_of_home_ownership !== null ? '✅Home Ownership' : '❌No home ownership' %> <br> <%= document.drivers_license !== null ? '✅DL License' : '❌No DL' %> <br> <%= document.fl_dl_check !== null ? '✅DL License Check' : '❌No DL check' %> <br> <%= document.created_on.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }) %></td> <td>✍️📧🗑️</td> </tr>
3. 验证下载函数逻辑
当前的downloadFile函数逻辑正确,只要传入标准Base64字符串,atob()就能正常解析生成Blob并触发下载。
替代方案(推荐大文件使用)
如果PDF文件较大,不建议在页面中渲染Base64字符串,可通过后端接口直接返回文件流:
后端新增下载接口
app.get('/download-pdf/:id', async (req, res) => { const { id } = req.params; // 查询数据库获取对应文档 const result = await pool.request() .input('id', sql.Int, id) .query('SELECT additional_documents FROM your_table WHERE id = @id'); const pdfData = result.recordset[0]?.additional_documents; if (!pdfData) return res.status(404).send('Document not found'); // 设置响应头触发下载 res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', `attachment; filename="additional_doc_${id}.pdf"`); res.send(pdfData); });
前端修改为直接调用接口
<a href="/download-pdf/<%= document.id %>" target="_blank">✅Additional Docs</a>
内容的提问来源于stack exchange,提问作者Tyler Ewing
相关产品推荐
相关产品推荐

