2017-07-25 128 views
0

我基本上正在嘗試製作一個小應用程序,允許管理員用戶輸入產品的名稱,價格和圖像,然後可以在另一個頁面上查看該應用程序。細節將被髮送到一個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."

和「文件」未定義。

回答

0

當使用multer保存圖像時,您需要確保圖像作爲表單數據來到服務器。這是因爲multer需要使用ajax請求提交表單時沒有得到的多部分/表單數據編碼,除非您專門做了一些事情來實現它。 您可以通過使用FormData對象來完成此操作。 Here是一個正在使用的例子。我希望這有幫助。

相關問題