使用MongoDB上传图像,表达,结点和反应

时间:2020-07-16 20:40:34

标签: node.js reactjs mongodb express multer

我一直在YouTube上关注这个很棒的教程,试图建立一个网站。但是,一旦部署,这些图像就不会显示出来,因为当前它们都保存在一个名为上载的本地文件夹中。这就是现在的样子:

服务器端

var storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, 'uploads/')
    },
    filename: (req, file, cb) => {
        cb(null, `${Date.now()}_${file.originalname}`)
    },
    fileFilter: (req, file, cb) => {
        const ext = path.extname(file.originalname)
        if (ext !== '.jpg' || ext !== '.png') {
            return cb(res.status(400).end('only jpg, png are allowed'), false);
        }
        cb(null, true)
    }
})

var upload = multer({ storage: storage }).single("file")

router.post("/uploadImage", auth, (req, res) => {

    upload(req, res, err => {
        if(err) return res.json({success: false, err})
        return res.json({ success: true, image: res.req.file.path, fileName: res.req.file.filename})
    })
   
});

客户端:图像字段存储一个字符串(即“ uploads \ xxxxxxxx.jpg”)

function ProductImage(props) {

    const [Image, setImage] = useState();

    useEffect(() => {
        setImage(`http://localhost:5000/${props.detail.image}`)
        

    }, [props.detail])
    
    return(
        <div>
            <img style={{maxWidth: '30vw'}} 
            src={Image} alt="productImg"/>
        </div>
    )
}

所以我想我现在的问题是,如何实际上将图像上传到MongoDB,以及如何检索它们?

2 个答案:

答案 0 :(得分:0)

首先,将原始图像数据存储在任何数据库中不是明智的选择。

您必须做三件事来处理文件:

1。在数据收集中创建一个字符串字段,用于在主机中存储文件名和希望存储图像的路径。

  1. 上传控制器:

在上载控制器中,您可以处理上载的逻辑,例如,存储数据,关于文件的验证,以及当文件降落到服务器中时,您可以将其路径存储在数据库中。

3。使用express保存您的静态文件:

router.use(
    "/avatar",
    express.static(path.join(__dirname, "../upload/avatar"))
);

答案 1 :(得分:0)

如果您将上传的图像存储在Heroku服务器中,则完全是浪费。因为Heroku Dyno每天都会重新启动,这将删除部署期间存储的数据以外的所有额外添加的数据。

要首先上载到MongoDB,您需要将其存储到服务器,multer会执行该工作,然后将其自动从heroku中删除。 下面的代码对您的数据进行加密,并根据ID将其上传到特定文档。

//Hashing and uploading to Mongodb 
fs.readFile('your file location', async function (err, data) {
    if (err) {
        console.log(err)
    } else {
        let iv = crypto.randomBytes(16);
        let pass = //I think 32 char password is required
        let cipher = crypto.createCipheriv('aes-256-ctr', pass, iv)
        let crypted = Buffer.concat([iv, cipher.update(data), cipher.final()]);


        console.log("crypted", crypted);
        let dataa = await User.findOne({
            _id: "Id of a MongoDB document"
        })
        //let buffer=new Buffer(data)
        dataa.files.push(crypted)
        await dataa.save()
        console.log("done")
    }

});

检索和解密数据

let data = await User.findOne({
    _id: "id of a MongoDB document"
})
console.log("dattttt", data.files[index of your image in mongoarray].buffer)


iv = data.files[index of your image in mongoarray].buffer.slice(0, 16);
chunk = data.files[index of your image in mongoarray].buffer.slice(16);
var decipher = crypto.createDecipheriv('aes-256-ctr', "same 32 char password here", iv)
var dec = Buffer.concat([decipher.update(chunk), decipher.final()]);

console.log("dec", dec);
let buffer = new Buffer.from(dec)
console.log("buffer", buffer)
fs.writeFile(`downloadable file location/filename.extension`, buffer, "binary", function (err, written) {
    if (err) console.log(err);
    else {
        console.log("Successfully written");
        res.sendFile((__dirname + `downloaded file location/filename.extension`))
    }
});