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

How to receive Cloudinary image URL immediately upon upload (React JS and Node Js)?

我可以成功上传图片到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}`)
});

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
}