如何使用JavaScript将HTML表单上传的图片以二进制存入PostgreSQL数据库
实现方案说明
首先明确:浏览器端原生JS无法直接连接PostgreSQL数据库(存在严重安全风险,也无官方支持的直连方案),因此需要拆分实现为「前端表单获取文件」+「Node.js后端接收文件并存入数据库」两部分,全程仅用原生API+PostgreSQL官方Node.js驱动,无额外框架。
第一步:前端HTML表单(原生无框架)
<!DOCTYPE html> <html> <body> <form id="uploadForm"> <input type="file" id="imgInput" accept="image/*" required> <button type="submit">上传图片</button> </form> <script> const form = document.getElementById('uploadForm'); form.addEventListener('submit', async (e) => { e.preventDefault(); const file = document.getElementById('imgInput').files[0]; const formData = new FormData(); formData.append('image', file); try { const res = await fetch('http://localhost:3000/upload', { method: 'POST', body: formData }); res.ok ? alert('上传成功') : alert('上传失败'); } catch (err) { console.error('请求出错', err); } }); </script> </body> </html>
第二步:Node.js后端实现(仅依赖PostgreSQL官方驱动pg,无其他框架)
首先安装必要依赖(仅为PG官方连接驱动,不属于业务框架):npm install pg
后端代码如下:
const http = require('http'); const { Client } = require('pg'); // PostgreSQL连接配置,和你提供的Java代码配置完全对应 const pgClient = new Client({ host: 'localhost', database: 'testdb', user: 'user12', password: '34klq*', port: 5432 }); // 初始化PG连接 pgClient.connect() .then(() => console.log('PostgreSQL连接成功')) .catch(err => console.error('PG连接失败', err)); // 原生HTTP服务,无第三方框架 const server = http.createServer(async (req, res) => { // 本地调试跨域配置,生产环境请修改为实际前端域名 res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', '*'); if (req.method === 'OPTIONS') { res.writeHead(200); res.end(); return; } // 处理上传请求 if (req.method === 'POST' && req.url === '/upload') { try { // 读取请求体二进制数据 const chunks = []; for await (const chunk of req) { chunks.push(chunk); } const buffer = Buffer.concat(chunks); // 解析FormData提取图片二进制内容 const boundary = req.headers['content-type'].split('boundary=')[1]; const parts = buffer.toString('binary').split(`--${boundary}`); const filePart = parts.find(part => part.includes('filename')); const fileContent = filePart.split('\r\n\r\n')[1].split('\r\n--')[0]; const imgBuffer = Buffer.from(fileContent, 'binary'); // 对应Java代码的插入逻辑,二进制存入bytea类型的data字段 const query = 'INSERT INTO images(data) VALUES($1)'; await pgClient.query(query, [imgBuffer]); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ success: true })); } catch (err) { console.error('处理出错', err); res.writeHead(500, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ success: false, error: err.message })); } return; } res.writeHead(404); res.end(); }); server.listen(3000, () => { console.log('服务启动在 http://localhost:3000'); });
注意事项
- 请确保PostgreSQL中
images表的data字段类型为bytea,和Java代码的表结构要求一致 - 生产环境请不要硬编码数据库账号密码,也不要开放全量跨域权限,上述配置仅为本地测试使用
- 如果需要处理更复杂的多文件、大文件上传场景,可以引入轻量的
formidable库做FormData解析,不需要修改核心存库逻辑
内容的提问来源于stack exchange,提问作者mucellakaya
相关产品推荐
相关产品推荐

