我基本上正在嘗試製作一個小應用程序,允許管理員用戶輸入產品的名稱,價格和圖像,然後可以在另一個頁面上查看該應用程序。細節將被髮送到一個mongo數據庫,該數據庫將通過前端的axios post進行。我可以發送名稱和價格沒有問題,可以在前端動態地看到,但是,我無法將圖像發送到我一直試圖實現了很長一段時間的mongo數據庫。使用Multer和Express以及Axios將圖像上傳到mongodb
我正在使用multer和axios嘗試發送文件,因爲應用程序是反應應用程序。我認爲問題在於應用程序後端的「req.file」。下面的代碼是我的終點:
api.js
var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors')
var app = express();
var mongodb = require('mongodb');
var path = require('path');
var fsextra = require('fs-extra');
var fs = require('fs')
var util = require('util')
var multer = require('multer')
var upload = multer({dest: __dirname + '/uploads'})
var ejs = require('ejs')
const MongoClient = require('mongodb').MongoClient;
app.use(express.static(path.resolve(__dirname, '../react', 'build')));
app.get('*',(req,res)=>{
res.sendFile(path.resolve(__dirname, '../react', 'build', 'index.html'));
});
console.log(__dirname)
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'public')));
app.set('views', __dirname);
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
var db;
mongodb.MongoClient.connect('mongodb://<mydbdetails>', (err, database) => {
if (err) {
console.log(err)
process.exit(1);
}
db = database;
console.log('Database connection is ready')
});
var server= app.listen(process.env.PORT || 8082, function() {
var port = server.address().port;
console.log("App now running on port", port);
});
app.post('/api/submitImage', upload.single('inputForm'), function(req,res){
var file = req.body.file
if (file == null) {
// If Submit was accidentally clicked with no file selected...
//res.render('admin', { title:'Please select a picture file to submit!'});
res.send({success: false, message: "dsfdsg"})
console.log('There is no file present')
console.log(req.file,'file')
}
else{
// read the img file from tmp in-memory location
var newImg = fs.readFileSync(req.files.path);
console.log(newImg,'details of the new image')
// encode the file as a base64 string.
var encImg = newImg.toString('base64');
console.log(encImg,'kdfjndodj')
// define your new document
var newItem = {
description: req.body.description,
contentType: req.file.mimetype,
size: req.files.size,
img: Buffer(encImg, 'base64')
};
db.collection('products').insert(newItem, function(err, result){
if(err) {
console.log(err)
}
var newoid = new ObjectId(result.ops[0]._id);
fs.remove(req.file.path, function(err) {
if (err) { console.log(err) };
res.render('./src/components/adminContainer.js', {title:'Thanks for the Picture!'});
});
})
}
})
下一個代碼是如何我嘗試過使用發送Axios公司:
import axios from 'axios';
class ProductsApi {
static submitProduct(name,prices,callback){
axios.post('http://localhost:8082/api/submitProduct', {name: name, prices: prices})
.then(response => {
callback(response)
})
}
static viewName(callback){
axios.post('http://localhost:8082/api/retrieveName')
.then(response => {
return callback(response)
})
}
static viewPrice(callback){
axios.post('http://localhost:8082/api/retrievePrice')
.then(response => {
return callback(response)
})
}
static viewProducts(callback){
axios.post('http://localhost:8082/api/retrieveProducts')
.then(response => {
return callback(response)
})
}
static submitImages(image,callback){
axios.post('http://localhost:8082/api/submitImage',{image: image})
.then(response => {
return callback(response)
console.log('response has been made,', image,'has been recieved by axios')
})
}
}
export default ProductsApi;
的最後一個文件是如何被我我試圖發送文件到數據庫使用與事件處理程序的反應:
import React, { Component } from 'react'
import '../App.css'
import AppHeader from './appHeader.js'
import ProductsApi from '../api/axios.js'
const AdminContainer =() => {
return(
<div>
<AppHeader />
<FormContainer />
</div>
)
}
class FormContainer extends Component{
constructor(props){
super(props);
this.state={
file: '',
inputName: '',
inputPrice: '',
image: ''
};
this.handleNameChange = this.handleNameChange.bind(this);
this.handlePriceChange = this.handlePriceChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.sendName = this.handleSubmit.bind(this);
}
handleNameChange(e){
console.log(e.target.value)
this.setState({
name : e.target.value,
})
}
handlePriceChange(e){
console.log(e.target.value)
this.setState({
prices : e.target.value
})
}
sendName(e){
this.setState({
inputName: e.target.value,
inputName:e.target.value
})
}
handleSubmit(e){
e.preventDefault();
console.log('attempting to access axios...')
ProductsApi.submitProduct(this.state.name, this.state.prices, resp => {
console.log('response has been made', resp)
//if error message, add to state and show error message on front end
this.setState({
inputName:this.state.name,
inputPrice:this.state.prices
},function(){
console.log(resp,'this is resp')
console.log('Axios has send ',this.state.name,' to the database')
});
})
console.log(this.state.prices,'This is the new price')
console.log(this.state.name,'This is the new name')
ProductsApi.submitImages(this.state.image, response => {
console.log('axios has been notified to submit an image...')
this.setState({
image: this.state.image
},function(){
console.log('Image submission axios response details are as follows: ', response)
console.log(this.state.image, ': has been sent to the db')
})
})
}
render(){
return(
<div>
<h2>Add a new product to the Shop</h2>
<div className='formWrapper'>
<div className='center'>
<form name='inputForm' encType='multipart/form-data' method='post'>
<label>
Name:
<input value = {this.state.name} onChange={this.handleNameChange} type="text" placeholder='Name' /><br />
Price:
<input value = {this.state.prices} onChange={this.handlePriceChange} type='text' /><br />
</label>
<label>
Choose an Image:
<input className='imgInsert' name ='inputForm' type='file'/>
</label>
<div>
<img className = 'previewImage' value={this.state.image}/>
</div>
<button className='btn updateBtn' onClick={(e) => this.handleSubmit(e)}>Submit</button>
</form>
</div>
</div>
</div>
)
}
}
export default AdminContainer
常見錯誤我得到時tr調試它是
TypeError: Cannot read property 'path' of undefined."
和「文件」未定義。