如何使用 React 前端从 Mongoose 显示带有 <img> 的图像
Posted
技术标签:
【中文标题】如何使用 React 前端从 Mongoose 显示带有 <img> 的图像【英文标题】:How to display an image with <img> from Mongoose using React front-end 【发布时间】:2018-11-07 19:21:46 【问题描述】:最终目标:让用户上传图片(小于 16mb,因此无需担心 Grid FS),通过 Mongoose 将图片存储在我的 Mongodb 数据库中,并使用属性将图片显示在屏幕上。
要上传文件,我使用 Multer 并将其添加到数据库中,如下所示:
newItem.picture.data = Buffer(fs.readFileSync(req.file.path), 'base64');
newItem.picture.contentType = 'image/png';
而且好像成功添加到mongodb了。看起来像这样: how the image appears on mongodb
我能够从我的前端发送一个获取请求,当我控制台记录它时,这就是我得到的:Data after being retreived from database。现在的问题是,如何将其添加到属性并在屏幕上显示图像。谢谢!
编辑:版主将问题标记为过于宽泛。很公平,我不太确定如何处理它。既然我能解决它,这就是我的前端的样子。
componentDidMount()
const PATH = "http://localhost:8080/apii/items/getitems";
axios.get(PATH)
.then(res =>
let picture64Bit = res.data[0].data.data
picture64Bit = new Buffer(x, 'binary').toString('base64');
this.setState(picture: picture64Bit)
)
.catch(err => console.log(err))
这里的关键是,1) res.data[0].data.data 等于随机数字列表。我把它转换回base64,所以它看起来和上面第一张来自mongodb的图片完全一样。然后,在 img 属性中内联显示它非常简单:
<img src = `data:image/png;base64,$this.state.picture` />
【问题讨论】:
【参考方案1】:您可以使用几个库,但我将任意选择Axios
进行演示。如果图像已经在 Mongo DB 中,这听起来不错。
您的目标是将照片从服务器获取到客户端,因此您需要一个函数来按需获取它们。您也可以调查fetch
或request
。
Axios:https://www.npmjs.com/package/axios
在 React 中,尝试这样的事情
async getPhotos()
const res = await Axios.get('/photos')
console.log('RESPONSE', res)
const photos = res.data
console.log('IMAGES', photos)
this.setState( photos )
这里有一个更完整的例子
import React, Component from 'react'
import Axios from 'axios'
class List extends Component
constructor(props) // super props allows props to be available
super(props) // inside the constructor
this.state =
photos : [], // Initialize empty list to assert existence as Array type
// and because we will retrieve a list of jpegs
error: '', // Initialize empty error display
componentDidMount()
this.getPhotos() // Do network calls in componentDidMount
async getPhotos()
try
const res = await Axios.get('/photos')
console.log('RESPONSE', res)
const photos = res.data
console.log('IMAGES', photos)
this.setState( photos, error: '' )
catch (e)
this.setState( error: `BRUTAL FAILURE: $e` )
render()
if (error.length)
return (
<div>this.state.error</div>
)
if (!photos.length)
return (
<div>No photos yet</div>
)
// Assuming shape id: 0, caption: 'Cats again', src: 'http://www.com/win.jpg'
// Make sure to include key prop when using map (for state management)
return (
<ul>
this.state.photos.map(photo => (
<li key=photo.id style= position: 'relative' >
<span>photo.caption</span>
<img src=photo.src
<div
className="overlay"
style=
position: 'absolute'
width: '100%',
height: '100%',
/>
</li>
))
</ul>
)
引用:In React.js should I make my initial network request in componentWillMount or componentDidMount?
如果您想在之后再获取一张照片,您应该尝试不可变地思考并将 this.state.photos
数组替换为自身的副本以及推送到数组末尾的新图像。为此,我们将使用扩展运算符对现有照片数组进行浅拷贝。这将允许 React 区分这两种状态并有效地更新新条目。
const res = await Axios.get('/photo?id=1337')
const photo = res.data
this.setState(
photos: [...photos, photo]
)
注意:秘诀是避免使用this.state.photos.push(photo)
。你必须在这样的设置状态上放置一个非法标志。
在 React 中,尝试考虑一种获取对象或数组的方法。一旦你想到了它,就把它扔进一个组件的状态。随着您进入 Redux,有时您最终会将项目存储在 Redux 存储中。这太复杂且没有必要现在描述。这些照片可能会通过 Redux Connect Function 以 this.props.photos
的形式提供。
在大多数情况下,组件的状态字段是存储组件感兴趣的任何内容的绝佳位置。
你可以把它想象成组件顶部的一个支架。
【讨论】:
感谢您的精彩回复!我能够让它工作,但我必须使用 Axios 做一件关键的事情。出于某种原因,它没有以“base 64”格式从服务器发送图片。那是一串随机数字,但没有字母。因此,在前端,我使用了一个函数将其转换为 base 64,然后按此处所述显示它:***.com/questions/42395034/…。不知道为什么会发生这种情况,因为在数据库上它显然是 64 基数(如图所示)所以一些澄清会很好哈哈。 你解决了吗?通过在那里阅读您的新笔记,您似乎能够将其转换为 base64 并成功显示。 我能够解决它,但我只是想了解为什么当我从数据库中提取图片时,它会更改编码方案/格式。在 mongo 中,图片以 base64 格式出现,但是当我从数据库中提取它时,它只是数字(i.stack.imgur.com/0ow2L.png)。如果没有发生这种奇怪的转换,那么整个问题就不会发生。以上是关于如何使用 React 前端从 Mongoose 显示带有 <img> 的图像的主要内容,如果未能解决你的问题,请参考以下文章
将 url id 从 react-router 传递给 mongoose
react_新手入门教程05——react + express + mongoose 实现CURD
将 Mongoose 数据库中的内容上传到 React 组件
如何从服务器端 express/mongo/mongoose 中的 URL,客户端的 axios/react/redux 中获取参数 ID