отправить изображение, взятое из ReactNativeCamera в Nodejs бэкэнд, который имеет multer? - PullRequest
0 голосов
/ 14 января 2020

У меня есть интерфейс с React native, и я реализовал следующее:

import React, {Component} from 'react';
import Config from 'react-native-config';
import {
  Button,
  Alert,
  Image,
  Text,
  View,
  StyleSheet,
  TouchableOpacity,
  Platform,
  CameraRoll,
} from 'react-native';
import {Container, Content, Icon} from 'native-base';
import {RNCamera} from 'react-native-camera';
import {SubHeader} from '../../components/headers';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column',
    backgroundColor: 'black',
  },
  preview: {
    flex: 1,
    justifyContent: 'flex-end',
    alignItems: 'center',
  },
  capture: {
    flex: 0,
    backgroundColor: '#fff',
    borderRadius: 5,
    padding: 15,
    paddingHorizontal: 20,
    alignSelf: 'center',
    margin: 20,
  },
});

export default class MainScreen extends Component {
  constructor(props) {
    super(props);
    this.state = {
      imageUri: null,
    };
  }

  test = async () => {
    if (this.camera) {
      const data = await this.camera.takePictureAsync({
        quality: 0.5,
        base64: true,
      });

      const photo = {
        name: data.fileName,
        type: data.type,
        uri:
          Platform.OS === 'android'
            ? data.uri
            : data.uri.replace('file://', ''),
      };

      this.setState({imageUri: data.uri}); //preview
      const fdata = new FormData();
      fdata.append('file', photo);

      try {
        let response = await fetch(`${Config.BASE_URL}/scan`, {
          method: 'POST',
          body: JSON.stringify(fdata),
          //body: fdata //this launches a connection error
        });
        const res = await response.json();

        return res;
      } catch (error) {
        console.error(error);
      }
    } else {
      Alert.alert('debug', 'There is no camera');
    }
  };

  render() {
    const {navigate} = this.props.navigation;

    return (
          <View style={styles.container}>
            <RNCamera
              ref={ref => {
                this.camera = ref;
              }}
              style={styles.preview}
              type={RNCamera.Constants.Type.back}
              flashMode={RNCamera.Constants.FlashMode.off}
              captureAudio={false}
              androidCameraPermissionOptions={{
                title: 'Permission to use camera',
                message: 'We need your permission to use your camera',
                buttonPositive: 'Ok',
                buttonNegative: 'Cancel',
              }}
              onGoogleVisionBarcodesDetected={({barcodes}) => {
                console.log(barcodes);
              }}
            />
            <View>
              <TouchableOpacity
                onPress={this.test.bind(this)}
                style={styles.capture}>
                <Icon type="FontAwesome" ios="camera" android="camera" />
              </TouchableOpacity>
            </View>
          </View>

           //preview
          <Image
            style={{width: 66, height: 58}}
            source={{
              uri: this.state.imageUri,
            }}
          />
        </View>
    );
  }
}

На сервере с nodeJs express и multer:

app.post('/scan', uploader.upload.single('file'), ScanController.scan);

Multer is well реализовано потому, что оно работает с почтальоном и с функциями веб-приложения внешнего интерфейса.

изображение отображается на устройстве android, но я всегда получаю неопределенный объект на сервере, я не знаю, как отправить это потому, что на базе 64, как я могу отправить его или получить правильно?

1 Ответ

0 голосов
/ 15 января 2020

Существует открытый вопрос См. Здесь о реакции native по этому поводу, но я нашел хорошее решение, используя rn-fetch-blob

, как вы можете видеть в документации вы можете реализовать следующее:

Сначала удалите экземпляр FormData, затем измените выборку для RNFetchBlob.fetch

Код следующим образом

upload = async () => {
    let ret = await RNFetchBlob.fetch(
      'POST',
      `${Config.BASE_URL}/scan`,
      {
        'Content-Type': 'multipart/form-data',
      },
      [
        {
          name: 'file',
          filename: Date.now() + '.png',
          type: 'image/png',
          data: RNFetchBlob.wrap(data.uri),
        },
      ],
    );
    return ret;
  };

Как вы видите, есть массив, куда вы можете добавлять объекты.

Реализация Multer и RNCamera остается прежней.

Надеюсь, это кому-нибудь может пригодиться!

...