无法将图片上传到 postgres 数据库
Posted
技术标签:
【中文标题】无法将图片上传到 postgres 数据库【英文标题】:cannot upload pictures to postgres database 【发布时间】:2018-04-14 09:56:29 【问题描述】:我在前端使用 React.js,在后端使用 Express.js API 来创建一个简单的博客。我正在为博客添加一项功能,以便能够上传图片和文件。我不断收到此错误。
error: invalid input syntax for type bytea
at Connection.parseE (C:\Users\Sophin\desktop\testingpostg\node_modules\pg\lib\connection.js:546:11)
at Connection.parseMessage (C:\Users\Sophin\desktop\testingpostg\node_modules\pg\lib\connection.js:371:19)
at Socket.<anonymous> (C:\Users\Sophin\desktop\testingpostg\node_modules\pg\lib\connection.js:114:22)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at readableAddChunk (_stream_readable.js:176:18)
at Socket.Readable.push (_stream_readable.js:134:10)
at TCP.onread (net.js:547:20)
name: 'error',
length: 93,
severity: 'ERROR',
code: '22P02',
detail: undefined,
hint: undefined,
position: '110',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'varlena.c',
line: '297',
routine: 'byteain'
POST /api/learning 400 69.873 ms - 131
这是我在 React.js 中的表单
import React, Component from 'react';
import logo from './logo.svg';
import './App.css';
import LearningFirstComp from './components/LearningFirstComp';
class App extends Component
constructor(props)
super(props);
this.state=
inputTopValue:'',
inputBottomValue:'',
inputImageValue:,
this.handleTopChange = this.handleTopChange.bind(this);
this.handleBottomChange = this.handleBottomChange.bind(this);
this.handleImageChange = this.handleImageChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
handleTopChange(event)
this.setState(inputTopValue: event.target.value);
console.log("changing")
handleBottomChange(event)
this.setState(inputBottomValue: event.target.value);
console.log("descr")
handleImageChange(event)
this.setState(inputImageValue: event.target.value)
console.log("imagechanged")
handleSubmit(event)
event.preventDefault();
fetch('api/learning',
method: 'POST',
headers: 'Content-Type': 'application/json',
body: JSON.stringify(
topstuff: event.target.topstuff.value,
bottomstuff: event.target.bottomstuff.value,
pic1: event.target.myimage.value
)
)
render()
return (
<div className="App">
<form onSubmit=this.handleSubmit encType="multipart/form-data">
<input type="text" name="topstuff" placeholder="title" onChange=this.handleTopChange value=this.state.inputTopValue /> <br/>
<input type="text" name="bottomstuff" placeholder="body" onChange=this.handleBottomChange value=this.state.inputBottomValue /><br/>
<input type="file" name="myimage" onChange=this.handleImageChange value=this.state.inputImageValue /><br/>
<input type="submit" value="Submit" />
</form>
<LearningFirstComp />
</div>
);
export default App;
我尝试在表单中同时使用“enctype”和“encType”,但都不起作用。
我的 postgresql 数据库的 Schema 如下所示
CREATE TABLE IF NOT EXISTS learningtable (
id BIGSERIAL PRIMARY KEY,
topstuff VARCHAR(255),
bottomstuff VARCHAR(255),
pic1 bytea
);
我想知道问题是否是因为错误的数据类型而发生的?我抬头发现要上传低于 1 MB 的图像,我们通常应该在 postgresql 中使用数据类型“bytea”。
这是我的 Express.js 路线
const express = require('express');
const myrouter = express.Router();
const controller = require('../controllers/learningController');
const multer = require('multer');
var storage = multer.diskStorage(
destination: function (req, file, cb)
cb(null, 'uploads')
)
var upload = multer( storage: storage );
myrouter.post('/', upload.single('myimage'), controller.create);
module.exports = myrouter;
我在这里使用 multer 上传文件,我认为这里一切正常?
这是我的 Express.js 控制器
const LearningObject = require('../models/learningmodel');
const controller = ;
controller.create = (req, res) =>
LearningObject.create(
topstuff: req.body.topstuff,
bottomstuff: req.body.bottomstuff,
pic1: req.body.pic1,
)
.then(jsonAfterAdding =>
res.json(
message: 'okay',
jsonAfterAdding: jsonAfterAdding
);
).catch(err =>
console.log(err);
res.status(400).json(err);
);
;
module.exports = controller;
最后,这是我的 Express.js 模型
const db = require('../db/config');
const LearningObject = ;
LearningObject.create = (randomparam) =>
return db.one (
`INSERT INTO learningtable
(topstuff, bottomstuff, pic1)
VALUES ($1, $2, $3) RETURNING *
`,
[randomparam.topstuff, randomparam.bottomstuff, randomparam.pic1]
);
;
module.exports = LearningObject;
任何帮助将不胜感激。
【问题讨论】:
这与你的 React 设置没有任何关系。 那会是什么? 还不确定,但它与 ReactJS 无关。我认为可以安全地排除这种可能性。您可能遇到表单提交问题,但在其他地方似乎更有可能。 修复了一个小问题,使错误消失,但仍然无法看到我文件夹中的图片。在我的handleSubmit
中,我在正文中发送了myimage
,它应该是pic1
,因为那是数据库表列的名称。但是还没有图片:(
请不要告诉我你是在动态使用myimage
来确定数据库表列的名称。你必须小心 SQL 注入。
【参考方案1】:
第一个问题(客户端)
您正在尝试使用 javascript Fetch 方法将文件上传到服务器,同时将请求 Content-Type 设置为 application/json。请求的类型必须是 multipart/form-data。
让我们为 html 表单分配一个 id 以便于参考:
<form id="myform" ...
现在我们需要获取表单元素并将其分配给一个变量:
var form = document.getElementById("myForm");
要将 fetch xhr 请求设置为 multipart/form-data Content-Type,我们需要将请求正文设置为绑定到表单元素的 FormData 对象:
body: new FormData(form)
第二个问题(服务器端)
无法访问 req.body 上上传的图片。 Multer 的专长是 multipart/form-data 请求,应用解析后的请求体与 body-parser 中间件略有不同。
我们可以通过请求file对象访问上传的图片数据。我们将通过 buffer 属性抓取图像的二进制数据。
pic1: req.file.buffer,
第三个问题(React DOM)
与浏览器 DOM 不同,React DOM 需要特殊处理。由于我们不能直接引用表单标签,所以我们需要将表单输入值存储在更改状态中。
对于文件,存储文件输入值是不够的。我们还需要存储文件object。由于我们只期望一个文件引用,我们将只获取数组中的 first 对象。
this.setState(inputImageValue: event.target.value,
inputImageFile: event.target.files[0])
现在在 handleSubmit 事件函数中,我们构建 FormData 对象并附加图像(附加顺序并不重要):
var formData = new FormData();
formData.append('myimage', this.state.inputImageFile);
然后我们附加输入字段的 rest:
formData.append('...', this.state...);
最后我们将 formData 分配给我们的请求正文:
body: formData
【讨论】:
在客户端喜欢这样?handleSubmit(event) var myform = document.getElementById("myform"); myform.append('topstuff', event.target.topstuff.value); myform.append('bottomstuff', event.target.bottomstuff.value); myform.append('pic1', event.target.myimage.value) fetch('api/learning', method: 'POST', headers: 'Content-Type': 'multipart/form-data', 'Accept': 'application/json' , body: new FormData(myform) )
抱歉,格式错误。我需要像上面那样附加值吗?由于某种原因它仍然不起作用:(以上是关于无法将图片上传到 postgres 数据库的主要内容,如果未能解决你的问题,请参考以下文章
php上传图片和显示,如何实现?或者有没有插件之类的? 上传到数据库是图片文件也行,图片名也行。