简体   繁体   English

将文件从移动设备发送到Node js服务器

[英]Send a file from mobile to Node js server

I'm doing an application with react-native. 我正在使用本机的应用程序。 Now I'm trying to send an image from the mobile to the server (Node Js). 现在,我正在尝试将图像从移动设备发送到服务器(节点Js)。 For this I'm using react-native-image-picker. 为此,我正在使用react-native-image-picker。 And the problem is that when I send the image it save a file but it's empty not contain the photo. 问题是,当我发送图像时,它保存了一个文件,但它是空的,不包含照片。 I think that the problem probably is that the server can't access to the path of the image because is in a different device. 我认为问题可能出在服务器位于另一台设备中,因此服务器无法访问图像的路径。 But I don't know how I can do it. 但是我不知道该怎么办。

React-Native: React-Native:

openImagePicker(){
      const options = {
        title: 'Select Avatar',
         storageOptions: {
          skipBackup: true,
          path: 'images'
      }
      }

      ImagePicker.showImagePicker(options, (imagen) =>{
          if (imagen.didCancel) {
        console.log('User cancelled image picker');
      }
      else if (imagen.error) {
        console.log('ImagePicker Error: ', imagen.error);
      }
      else if (imagen.customButton) {
        console.log('User tapped custom button: ', imagen.customButton);
      }
      else {
    let formdata = new FormData();
    formdata.append("file[name]", imagen.fileName);
    formdata.append("file[path]", imagen.path);
    formdata.append("file[type]", imagen.type);
            fetch('http://X/user/photo/58e137dd5d45090d0b000006', {
      method: 'PUT',
      headers: {
         'Content-Type': 'multipart/form-data'
      },
      body: formdata
    })
        .then(response => {
          console.log("ok");       
      })
       .catch(function(err) {
          console.log(err);
      })  
    }})}

Node Js: 节点Js:

    addPhotoUser = function (req, res) {
User.findById(req.params.id, function(err, user) {
fs.readFile(req.body.file.path, function (err, data) {      
  var pwd = 'home/ubuntu/.../';
  var newPath = pwd + req.body.file.name;
  fs.writeFile(newPath, data, function (err) {
    imageUrl: URL + req.body.file.name;
        user.save(function(err) {
            if(!err) {
                console.log('Updated');
            } else {
                console.log('ERROR: ' + err);
            }
            res.send(user);
        });

  });
});
});
};

Make an object then send that object to the server. 制作一个对象,然后将该对象发送到服务器。 The object will consist of name,path and type, like this: 该对象将由名称,路径和类型组成,如下所示:

var imageData = {name: 'image1', path: uri, type: 'image/jpeg'} 

Above is a one way to send the image data. 以上是发送图像数据的一种方法。 The other way is to convert it into BLOB so that server side programmer doesn't have to do this task on their end. 另一种方法是将其转换为BLOB,这样服务器端程序员就不必在其末端执行此任务。 You can make BLOB by use of react-native-fetch-blob . 您可以使用react-native-fetch-blob来制作BLOB。

One more way is to directly upload the images to the amazon server(s3) and send the link to the backend.. 另一种方法是将图像直接上传到亚马逊服务器,然后将链接发送到后端。

Function that returns base64 string: 返回base64字符串的函数:

var RNFetchBlob = require('react-native-fetch-blob').default;

getImageAttachment: function(uri_attachment, mimetype_attachment) {

  return new Promise((RESOLVE, REJECT) => {

    // Fetch attachment
    RNFetchBlob.fetch('GET', config.apiRoot+'/app/'+uri_attachment)
      .then((response) => {

        let base64Str = response.data;
        var imageBase64 = 'data:'+mimetype_attachment+';base64,'+base64Str;
        // Return base64 image
        RESOLVE(imageBase64)
     })

   }).catch((error) => {
   // error handling
   console.log("Error: ", error)
 });
},

Cheers :) 干杯:)

Yes, the problem is that the filepath is on the local device and not the server. 是的,问题在于文件路径位于本地设备而非服务器上。 You want to send the actual data returned to you by react-native-image-picker not the uri. 您想通过react-native-image-picker而不是uri发送返回给您的实际数据。 It looks like that library encodes the data with base64 so you're going to want send that to your server, not the uri returned from the library because it won't be accessible on a remote server. 好像该库使用base64编码了数据,因此您将需要将其发送到服务器,而不是从库返回的uri,因为它无法在远程服务器上访问。

What this means is that you won't be reading any files on your server but instead just decoding a base64 string in the response body and writing that to your filesystem. 这意味着您将不会读取服务器上的任何文件,而只会在响应正文中解码base64字符串并将其写入文件系统。

For the client side: 对于客户端:

let formdata = new FormData();
formdata.append("file[name]", imagen.fileName);
formdata.append("file[data]", imagen.data); // this is base64 encoded!
formdata.append("file[type]", imagen.type);
        fetch('http://X/user/photo/58e137dd5d45090d0b000006', {
  method: 'PUT',
  headers: {
     'Content-Type': 'multipart/form-data'
  },
  body: formdata
})

On the server side atob to decode from base64 before writing to the filesystem: 在服务器端, atob可以在写入文件系统之前从base64进行解码:

let decoded = atob(req.body.data) 
// now this is binary and can written to the filesystem

From there: 从那里:

fs.writeFile(newPath, decoded, function (err) {
    imageUrl: newPath;
        user.save(function(err) {
            if(!err) {
                console.log('Updated');
            } else {
                console.log('ERROR: ' + err);
            }
            res.send(user);
        });

  });

Note, you don't need the filesystem write that's in your code because you're decoding the image that was sent as a b64 string in your request. 请注意,您不需要代码中的文件系统写操作,因为您正在解码在请求中作为b64字符串发送的图像。

There also seems to be some oddities with how you're using that user object. 您使用该用户对象的方式似乎也有些奇怪。 You seem to be only passing a function that handles errors and not any actual data. 您似乎只传递处理错误的函数,而不传递任何实际数据。 I don't know what ORM you're using so it's hard to say how it should work. 我不知道您正在使用什么ORM,因此很难说它应该如何工作。 Maybe something like this? 也许是这样的吗?

user.save({imageUrl:uriReturnedByFsWrite}, (err, data)=>{...})

Good luck :) 祝好运 :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM