如何在上传后立即接收 Cloudinary 图像 URL(React JS 和 Node Js)?

Posted

技术标签:

【中文标题】如何在上传后立即接收 Cloudinary 图像 URL(React JS 和 Node Js)?【英文标题】:How to receive Cloudinary image URL immediately upon upload (React JS and Node Js)? 【发布时间】: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 
              
              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`)
);

【问题讨论】:

【参考方案1】:

Cloudinary 上传响应对象包含一个secure_url 属性,您可以将其发送回前端。查看代码 #2,您似乎正在发送“成功”消息 (res.json(msg: "Success"))。听起来您想将该行更改为 -

res.json(url: uploadedResponse.secure_url)

在您的前端(代码 #1)中,我会考虑从 async/await 切换到 .then 机制,因为您不希望整个应用程序等待响应 -

const uploadImage = (base64EncodedImage) => 
  console.log(base64EncodedImage);
  fetch('/api/upload', 
      method: 'POST',
      body: JSON.stringify(data: base64EncodedImage),
      headers: 'Content-type': 'application/json'
    )
    .then(doWhateverYouWant)
    .catch((error) => console.error(error))


const doWhateverYouWant = async (res) => 
// you can use res.url

【讨论】:

以上是关于如何在上传后立即接收 Cloudinary 图像 URL(React JS 和 Node Js)?的主要内容,如果未能解决你的问题,请参考以下文章

上传到 Cloudinary 后图像被截断

在 Android 中将图像上传到 Cloudinary 失败

Rails Cloudinary 提交后直接上传图片

如何将图像上传到 Cloudinary - MERN 堆栈

如何将缓冲区图像上传到 cloudinary?

如何将图像从 android 上传到 Cloudinary?