React Native(Expo)上传文件到Node(Multer)

5

如何使用expo从React Native上传文件(PDF、文档等)到服务器,并使用node。我看过很多使用expo image-picker API的示例,但没有看到使用Expo的document-picker或file system API的示例。Expo文件系统文档对像我这样的初学者来说有点难以理解。

4个回答

9

感谢您的帮助。我已经想出了一种解决方案,并将其发布在下面,以便未来来到这里的人可以受益。

React Native

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

干杯!!!


这个解决方案对我来说是正确的,非常感谢!! - Rafael Mora
对我不起作用 - 我使用你的解决方案时出现了 TypeError: Network Error。 - yesIamFaded

2
如果@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:// 协议。

该问题可能在下一版本中得到解决。


0

嘿,我尝试了这个,但是它抛出了几个错误。 - Anandhu

0

1
嘿,以下示例使用图像选择器,就像您提到的那样,我确实想要使用FileSystem或DocumentPicker。是否有任何使用这两个的示例?如果有,那会帮助我解决问题!谢谢! - Anandhu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接