react-native - 如何将 react-native 图像从 expo-image-picker 上传到使用 multer 的 Express.js 后端

标签 react-native express expo multer

正如标题所说,我正在尝试使用 expo-image-picker 和 express.js 后端上传图片

博览会代码:

const 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();
  const dataa = Object.values(pickerResult);
  var data = new FormData();
  data.append('image', {
    path: dataa[2], //image uri
    originalname: "profilePic" + userId + ".jpg",
    type: "image/jpg",
    fieldname: "demo_image"
  })
  console.log(data)
  const uploadImage = await axios.post(`http://localhost:8000/api/upload/picture/` + userId, data);
}

express 代码

路由器:

var multer = require("multer")
var storage = multer.diskStorage({
  destination: function(req, file, cb) {
    console.log(file)
    cb(null, './controllers/assets/profilePic/');
  },
  filename: function(req, file, cb) {
    console.log(file)
    cb(null, file.originalname);
  }
});
var upload = multer({
  storage: storage
}).single("demo_image");
router.route("/upload/picture/:userId").post(upload, UserController.updatePhoto)

更新照片功能:

static updateGamePhoto = async (req, res) => {
  try {
    const query = await GamMdl.find({
      game_id: req.params.gameId
    })
    console.log(req.file)
    if (query.length > 0) {
      //get file route
      //get route to db
      const queryy = await GamMdl.updateOne({
        game_id: req.params.gameId
      }, {
        picture: req.file.originalname
      })
      console.log(queryy)
      res.send("1")
    } else {
      //vymaz file
      fs.unlinkSync(req.file.path)
      res.send("0")
    }
  } catch (error) {
    console.log(error)
  }
}

我得到的错误是

2022-04-10T18:17:29.165105+00:00 app[web.1]: undefined
2022-04-10T18:17:29.165435+00:00 app[web.1]: TypeError: Cannot read properties of undefined (reading 'originalname')
2022-04-10T18:17:29.165436+00:00 app[web.1]:     at updatePhoto (/app/controllers/userController.js:166:119)
2022-04-10T18:17:29.165436+00:00 app[web.1]:     at runMicrotasks (<anonymous>)
2022-04-10T18:17:29.165439+00:00 app[web.1]:     at processTicksAndRejections (node:internal/process/task_queues:96:5)

这很可能意味着该对象未被传递或无法被正确解析。

当我使用 Postman 测试仅通过后端上传图片时一切正常。 postman 预设:

postman preset

如何解决这个问题?

最佳答案

不要使用 axios 进行文件上传,因为您需要从 native 文件系统读取图像。您可以使用 Expo 的 FileSystem 模块中的 uploadAsync()Documentation Here

在您的情况下,函数调用将是:

const 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) {
    const uploadResult = await FileSystem.uploadAsync('http://localhost:8000/upload/picture/1', pickerResult.uri, {
      httpMethod: 'POST',
      uploadType: FileSystemUploadType.MULTIPART,
      fieldName: 'demo_image'
    });
  }
}

顺便说一句,请避免使用 localhost,因为该应用程序可能会在设备或模拟器上运行,而 localhost 将是设备本身,而不是您的网络服务器。通过环境变量传递 API 端点。更多信息 here .在开发过程中使用类似 dotenv 的东西来加载变量。

关于react-native - 如何将 react-native 图像从 expo-image-picker 上传到使用 multer 的 Express.js 后端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71819433/

相关文章:

android - React-native 应用程序不会在后退按钮上关闭

android - 在现有的 React Native iOS 项目中安装 React-Native Android?

node.js - 对不同端口中不同应用程序的 http 请求

node.js - Node.js-如何接收和解析multipart/formData作为具有字段和文件的对象数组?

react-native - 安装 'expo start' 后无法运行 "@react-navigation/web"命令

javascript - expo sdk 40 metro.config.js "Expected ' fromDir' 为 'string' ,得到 'undefined' “

react-native - 如何将调度函数传递给 Header 组件?

javascript - jsdoc - 如何使用 Express.js 请求和响应作为参数类型

react-native - 捕获 Ref 或自定义从 JSX/HTML 生成图像 react native 而不向用户显示 UI

react-native - React Native Expo 应用程序如何从通知中注销