【问题标题】:How to upload image to node js server from react native (expo) using fetch如何使用 fetch 从 react native(expo)上传图像到节点 js 服务器
【发布时间】:2021-09-02 07:51:35
【问题描述】:

我没有在服务器端接收数据。有时我将数据作为对象。我尝试了不同的方法,但图像上传失败。下面是我的代码。我尝试了不同的方法,但结果是相同的图像文件夹仍然为空,因为我使用 multer 中间件

图像正在使用这个 sn-p 显示

<TouchableHighlight
  style={[
    styles.profileImgContainer,
    { borderColor: "#4632a1", borderWidth: 1 },
  ]}
  onPress={openImagePickerAsync}
>
  <Image source={{ uri: selectedImage.localUri }} style={styles.thumbnail} />
</TouchableHighlight>

这是图像选择器部分

function PickImage() {
  let [selectedImage, setSelectedImage] = useState("");
  let openImagePickerAsync = async () => {
    let permissionResult =
      await ImagePicker.requestMediaLibraryPermissionsAsync();

    if (permissionResult.granted === false) {
      alert("Permission to access camera roll is required!");
      return;
    }

    let pickerResult = await ImagePicker.launchImageLibraryAsync();
    if (pickerResult.cancelled === true) {
      return;
    }

    setSelectedImage({ localUri: pickerResult.uri });
  };
}

获取 API 调用

async function upload() {
  const data = new FormData();
  data.append("image", {
    uri: selectedImage.uri,
    name: selectedImage.title,
    type: selectedImage.type,
  });

  const setting = {
    method: "POST",
    headers: {
      "Content-Type": "multipart/form-data;",
    },
    body: data,
  };
  try {
    const fetchResponse = await fetch(url, setting);
    const data = await fetchResponse.json();
    alert(data);
  } catch (e) {
    alert(e);
  }
}

服务器端代码

app.post("/users", upload.single("image"), async (req, res) => {
  console.log(req.body.file);
  console.log(req.body);
  const img = req.body.image;
  if (!img) {
    console.log("no image");
  }

  res.send({ congrats: "data recieved" });
});

【问题讨论】:

    标签: react-native express expo multer


    【解决方案1】:

    首先,ImagePicker 不返回标题和 mimeType。把状态更新逻辑改成这个

    setSelectedImage({
      uri: result.uri,
      name: 'SomeImageName.jpg',
      type: 'image/jpg',
    });
    

    也把你的上传功能改成这个,(我最喜欢写POST请求的方式)

    async function upload() {
      try {
        const data = new FormData();
        data.append("image", selectedImage);
    
        await fetch(URL_Endpoint, {
          method: "POST",
          body: data,
        });
      } catch (error) {
        console.log(error);
      }
    }
    

    其次,在服务器端,像这样使用它

    您可以通过两种方式管理文件

    1.) 磁盘存储

    像这样定义 multer 配置

    const express = require("express");
    const app = express();
    const multer = require("multer");
    
    const storage = multer.diskStorage({
      destination: "./uploads/",
      filename: function (req, file, cb) {
        cb(null,  "SomeImage" + "." + file.originalname.split(".").pop());
      },
    });
    
    const diskStorage = multer({ storage: storage });
    

    然后,

    app.post("/users", diskStorage.single("image"), async (req, res) => {
      try {
        console.log(req.file); // File which is uploaded in /uploads folder.
        console.log(req.body); // Body
        res.send({ congrats: "data recieved" });
      } catch (error) {
        res.status(500).send("Error");
      }
    });
    

    2.) 内存存储

    像这样定义 multer 配置

    const express = require("express");
    const app = express();
    const fs = require("fs");
    const multer = require("multer");
    
    const memoryStorage = multer({
      storage: multer.memoryStorage(),
    });
    

    然后,

    app.post("/users", memoryStorage.single("image"), async (req, res) => {
      try {
        console.log(req.file);
        console.log(req.body);
    
        // Here you will have to save it manually
    
        const DirName = `./uploads`;
        let URL = `./uploads/SomeImage.` + req.file.originalname.split(".").pop();
    
        fs.mkdir(DirName, { recursive: true }, async (err) => {
          if (err) {
            return res.status(500).send("Some Error");
          } else {
            fs.writeFile(URL, req.file.buffer, "ascii", function (err) {
              if (err) {
                return res.status(500).send("Some Error");
              } else {
                res.send({ congrats: "data recieved" });
              }
            });
          }
        });
      } catch (error) {
        res.status(500).send("Error");
      }
    });
    

    【讨论】:

    • 正在接收对象但无法析构它
    【解决方案2】:

    我尝试了不同的方法来通过 fetch 和 axios API 发送我的文件,但是 multer 无法找到我的图像 uri,因为它接受文件,所以你可以简单地将你的图像 uri 字符串化并将其发送到你的节点服务器

    axios 接口

    const formData=new FormData()
      var imageJSON = {
        imageName:new Date().getTime()+"_profile",
        avatar:selectedImage,
        name:name,
        email:email,
        SocietyCode:sCOde,
        password:Password
      }
    
      formData.append('image', JSON.stringify(imageJSON))
    
      axios.post('http://localhost:3000/users',formData,{
        headers:{
          Accept: 'application/json',
          'Content-Type':'multipart/form-data'
        }
      }).then((responseData) => {
        console.log("before",responseData.data)
          
        })
        .catch((error) => {
          alert(error)
          console.log("ERROR " + error.message)
        });
    

    节点服务器端代码

    router.post('/users', upload.single('avatar'), async (req,res)=>{
          
            formData =await req.body;
            var userJSON =await JSON.parse(formData.image);
        
      const avatar =await Buffer.from(userJSON.avatar, "utf-8");
    
      delete userJSON.avatar
    userJSON.avatar=avatar
    console.log(userJSON)
    
    
     const user= new Users(userJSON)
            try{
    
              
                await user.save()
                res.send({'message':'Registeration Successfull'})
    
            }
            catch(e){
                res.send({'response':'registeration failed'})
                console.log(e)
            }
              
          })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-23
      • 2021-12-31
      • 2021-05-29
      • 2021-06-07
      • 2023-01-06
      • 2016-12-06
      • 2021-09-18
      • 1970-01-01
      相关资源
      最近更新 更多