【问题标题】:File upload from React Native ( expo ) to Node ( multer )文件从 React Native ( expo ) 上传到 Node ( multer )
【发布时间】:2021-01-02 18:29:25
【问题描述】:

如何使用 expo 从 React Native 上传文件(pdf、文档等)到使用 node.js 的服务器。我见过很多使用 expo image-picker api 的图像示例,但我没有遇到使用 expo 中的 document-picker 或文件系统 api 的示例。对于像我这样的初学者来说,expo 文件系统文档有点难以理解。

【问题讨论】:

    标签: node.js react-native expo multer


    【解决方案1】:

    感谢您的帮助。我想出了一个解决方案,并将其发布在下面,以便将来来这里的任何人都可以使用它。

    反应原生

    import React, { useState } from 'react';
    import { Button, View } from 'react-native';
    import * as DocumentPicker from 'expo-document-picker';
    import * as FileSystem from 'expo-file-system';
    
    const DocPicker = () => {
        const [ doc, setDoc ] = useState();
        const pickDocument = async () => {
            let result = await DocumentPicker.getDocumentAsync({ type: "*/*", copyToCacheDirectory: true }).then(response => {
                if (response.type == 'success') {          
                  let { name, size, uri } = response;
                  let nameParts = name.split('.');
                  let fileType = nameParts[nameParts.length - 1];
                  var fileToUpload = {
                    name: name,
                    size: size,
                    uri: uri,
                    type: "application/" + fileType
                  };
                  console.log(fileToUpload, '...............file')
                  setDoc(fileToUpload);
                } 
              });
            // console.log(result);
            console.log("Doc: " + doc.uri);
        }
    
        const postDocument = () => {
            const url = "http://192.168.10.107:8000/upload";
            const fileUri = doc.uri;
            const formData = new FormData();
            formData.append('document', doc);
            const options = {
                method: 'POST',
                body: formData,
                headers: {
                  Accept: 'application/json',
                  'Content-Type': 'multipart/form-data',
                },
            };
            console.log(formData);
    
            fetch(url, options).catch((error) => console.log(error));
        }
    
        return (        
            <View>
                <Button title="Select Document" onPress={pickDocument} />
                <Button title="Upload" onPress={postDocument} />
            </View>
        )
    };
    
    export default DocPicker;
    

    Node.js

    const express = require('express')
    const bodyParser = require('body-parser')
    var multer  = require('multer')
    var upload = multer({ dest: 'uploads/' })
    const app = express()
    const fs = require('fs')
    const http =  require('http')
    const port = 8000
    
    
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));
    
    app.get('/', (req,res) => {
        res.json({
            success: true
        })
    })
    
    
    app.post('/', (req, res) => {
        console.log(req.body)
        res.status(200)
      })
    
    app.post('/upload', upload.single('document'),(req , res) => {
      console.log(req.file, req.body)
    });
    
    app.listen(port, () => {
      console.log(`Example app listening at http://localhost:${port}`)
    })
    

    干杯!!!

    【讨论】:

      【解决方案2】:

      【讨论】:

      • 嘿,我试过了,但它给我带来了一些错误
      【解决方案3】:

      这里是一个例子,后端也使用了multer和express:https://github.com/expo/examples/tree/master/with-formdata-image-upload

      也就是说,我建议使用 FileSystem.uploadAsync 而不是 fetch 和后台 sessionType,以便在应用程序在 iOS 上作为后台时支持上传。

      【讨论】:

      • 嘿,下面的示例使用图像选择器,就像您提到的那样,我确实想使用 FileSystem 或 DocumentPicker。有没有这两者中的任何一个的例子?如果是,那将帮助我解决!谢谢!
      【解决方案4】:

      如果@Anandhu 给出的解决方案不起作用,那么试试上面这样的代码。

      import React, { useState } from 'react';
      import { Button, View } from 'react-native';
      import * as DocumentPicker from 'expo-document-picker';
      import * as FileSystem from 'expo-file-system';
      
      const DocPicker = () => {
          const [ doc, setDoc ] = useState();
          const pickDocument = async () => {
              let result = await DocumentPicker.getDocumentAsync({ 
               type: "*/*", 
               copyToCacheDirectory: true })
                .then(response => {
                  if (response.type == 'success') {          
                    let { name, size, uri } = response;
      
                 / ------------------------/
                    if (Platform.OS === "android" && uri[0] === "/") {
                       uri = `file://${uri}`;
                       uri = uri.replace(/%/g, "%25");
                    }
                / ------------------------/
      
                    let nameParts = name.split('.');
                    let fileType = nameParts[nameParts.length - 1];
                    var fileToUpload = {
                      name: name,
                      size: size,
                      uri: uri,
                      type: "application/" + fileType
                    };
                    console.log(fileToUpload, '...............file')
                    setDoc(fileToUpload);
                  } 
                });
              // console.log(result);
              console.log("Doc: " + doc.uri);
          }
      
          const postDocument = () => {
              const url = "http://192.168.10.107:8000/upload";
              const fileUri = doc.uri;
              const formData = new FormData();
              formData.append('document', doc);
              const options = {
                  method: 'POST',
                  body: formData,
                  headers: {
                    Accept: 'application/json',
                    'Content-Type': 'multipart/form-data',
                  },
              };
              console.log(formData);
      
              fetch(url, options).catch((error) => console.log(error));
          }
      
          return (        
              <View>
                  <Button title="Select Document" onPress={pickDocument} />
                  <Button title="Upload" onPress={postDocument} />
              </View>
          )
      };
      
      export default DocPicker;
      

      路径的编码方式存在错误,并且缺少 file:// 方案。

      此错误可能会在下一版本中修复。

      【讨论】:

        猜你喜欢
        • 2021-08-29
        • 2020-09-04
        • 2022-06-21
        • 1970-01-01
        • 2021-11-30
        • 2017-03-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-09
        相关资源
        最近更新 更多