2017-05-08 56 views
0

我在做与反应原生的应用程序。现在我试图从手机发送图像到服务器(Node Js)。为此,我使用react-native-image-picker。问题是,当我发送图像时它保存一个文件,但它是空的不包含照片。我认为这个问题可能是因为在不同的设备,服务器无法访问到图像的路径。但我不知道我该怎么做。将文件发送到节点JS服务器

阵营母语:

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

节点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); 
     }); 

    }); 
}); 
}); 
}; 

回答

1

做一个对象,然后发送对象到服务器。该对象将包含名称,路径和类型,如下所示:

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

以上是发送图像数据的一种方法。另一种方法是将其转换成BLOB使服务器端程序员不必做他们结束这个任务。您可以使用react-native-fetch-blob来制作BLOB。

另一种方式是直接上传图片到亚马逊服务器(S3),并发送链接到后端..

函数返回的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) 
}); 
}, 

干杯:)

+0

谢谢!我试着第一个解决方案。我在后台发送它很好,但在尝试访问映像时没有正确保存并且没有显示任何内容。 –

+0

真的发生了什么? – Codesingh

+0

看到我上面的答案。手机中的uri无法远程访问。当他试图读取它时,他正试图读取uri在手机上的图像。 – klvs

1

是的,问题是,文件路径是本地设备,而不是在服务器上。你想发送由react-native-image-picker返回给你的实际数据而不是uri。它看起来像库的base64所以你会想发送到您的服务器对数据进行编码,而不是URI从库返回,因为它不会是一个远程服务器上访问。

这意味着你不会读取服务器上的任何文件,而只是在响应主体中解码base64字符串并将其写入文件系统。

对于客户端:

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

在服务器端atob从的base64解码之前写入文件系统:

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

从那里:

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

    }); 

注,你不需要你的代码中的文件系统编写,因为你正在解码那个图像在您的请求中作为b64字符串发送。

这似乎也与你如何使用该用户对象有一些古怪。你似乎只传递一个处理错误的函数,而不是任何实际的数据。我不知道你在使用什么ORM,所以很难说它应该如何工作。也许这样?

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

祝你好运:)

相关问题