【发布时间】:2021-12-09 12:42:26
【问题描述】:
我可以成功上传图片到 Cloudinary。但我的问题是如何在上传后立即将成功上传图片的 Cloudinary url 发回给我?
我知道它是作为const uploadedResponse = await cloudinary.uploader.upload(fileStr, {upload_preset: 'dev_setups'}) 的一部分发回的,但这是在后端(参见下面的代码 #2),我想在前端接收 URL(参见下面的代码 #1)所以我可以设置它到 React 状态。实现这一目标的最佳方法是什么?
如果您需要更多详细信息,请告诉我。
代码#1:下面是我上传图片到 Cloudinary 的代码(Cloudinary 的具体代码在下面注释,以供参考/* Cloudinary upload */)
import React, { useState } from 'react'
import { Card, Button, CardContent } from '@material-ui/core';
import { post, makePostAction } from '../actions';
import { useSelector, useDispatch } from 'react-redux';
export default function MakePost() {
const [title, setTitle] = useState("")
const dispatch = useDispatch();
const usernameHandle = useSelector(state => state.username)
const [fileInputState, setFileInputState] = useState('') /* new */
const [previewSource, setPreviewSource] = useState('') /* new */
const [selectedFile, setSelectedFile] = useState('') /* new */
const onInputChange = (event) => {
setTitle(event.target.value);
}
const handleSubmit = (evt) => {
evt.preventDefault();
if (!title) return
dispatch(makePostAction({
title,
comment: false,
comments_text: "",
handle: usernameHandle,
post_date: new Date().getTime()
}))
setTitle("")
}
/* Cloudinary upload */
const handleFileInputChange = (e) => {
const file = e.target.files[0]
previewFile(file)
}
const previewFile = (file) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = () => {
setPreviewSource(reader.result)
}
}
const handleSubmitFile = (e) => {
e.preventDefault();
if(!previewSource) return;
uploadImage(previewSource)
}
const uploadImage = async (base64EncodedImage) => {
console.log(base64EncodedImage)
try {
await fetch('/api/upload', {
method: 'POST',
body: JSON.stringify({data: base64EncodedImage}),
headers: {'Content-type': 'application/json'}
})
} catch (error) {
console.error(error)
}
}
/* Cloudinary upload */
return (
<div>
<Card>
<CardContent>
<form onSubmit={handleSubmit}>
<input type="text" value={title} onChange={onInputChange} />
</form>
{/* new */}
<form onSubmit={handleSubmitFile} className="form">
<input type="file" name="image" onChange={handleFileInputChange} value={fileInputState} className="form-input" />
<button className="btn" type="submit">Submit</button>
</form>
{/* new */}
{previewSource && (
<img
src={previewSource}
alt="chosen"
style={{height: '300px'}}
/>
)}
</CardContent>
</Card>
</div>
)
}
代码 #2:这是我的 server.js
const express = require('express');
const app = express();
const {cloudinary} = require('./utils/cloudinary');
app.use(express.json({limit: '50mb'}));
app.use(express.urlencoded({limit: '50mb', extended: true}))
app.get('/api/images', async (req, res) => {
const {resources} = await cloudinary.search.expression('folder:dev_setups')
.sort_by('public_id', 'desc')
.max_results(1)
.execute()
const publicIds = resources.map(file => file.secure_url)
res.send(publicIds)
})
app.post('/api/upload', async (req, res) => {
try {
const fileStr = req.body.data;
const uploadedResponse = await cloudinary.uploader.upload(fileStr, {upload_preset: 'dev_setups'})
res.json({msg: "Success"})
} catch (error){
console.error(error)
res.status(500).json({err: 'Something went wrong'})
}
})
const port = process.env.PORT || 3001
app.listen(port, () => {
console.log(`listening on port ${port}`)
});
【问题讨论】:
标签: node.js reactjs cloudinary