如何使用 fetch 从 React Native (expo) 将图像上传到节点 js 服务器

How to upload image to node js server from react native (expo) using fetch

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

正在使用此代码段显示图片

<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" });
});

首先,ImagePicker没有return标题和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);
  }
}

其次,在server-side上,这样使用

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

1.) 磁盘存储

像这样定义多个配置

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.) 内存存储

像这样定义多个配置

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");
  }
});

我尝试了不同的方法通过 fetch 和 axios 发送我的文件 API 但是 multer 无法找到我的图像 uri,因为它接受文件所以你可以简单地将你的 uri 字符串化而不是进入那些东西图片并将其发送到您的 nodejs 服务器

axiosApi

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)
        }
          
      })