【问题标题】:Can't Upload an image from Expo& React Native and POST to a flask backend无法从 Expo& React Native 上传图像并 POST 到烧瓶后端
【发布时间】:2020-08-28 11:36:13
【问题描述】:

我正在尝试使用 react native/expo 上传图像,并将其发送到 Python Flask 后端服务器。但是,在我的 Flask 服务器中,我遇到了这个错误:werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent an request that this server could not understand.

这是上传图片的代码(效果很好):

import React from "react";
import {
  StyleSheet,
  Text,
  View,
  Image,
  Button,
  Alert,
  TouchableOpacity,
} from "react-native";
import * as ImagePicker from "expo-image-picker";
import * as Permissions from "expo-permissions";
import { editProfilePicture } from "../functions/network_authentication";
import { onPressHandler } from "../functions/utils";

export default class EditPicture extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {
      image: null,
    };
  }
  handleChange(event) {
    this.setState({
      image: event,
    });
    console.log("handle change ok");
    console.log(this);
  }
  askForPermission = async () => {
    const permissionResult = await Permissions.askAsync(Permissions.CAMERA);
    if (permissionResult.status !== "granted") {
      Alert.alert("no permissions to access camera!", [{ text: "ok" }]);
      return false;
    }
    return true;
  };

  takeImage = async () => {
    // make sure that we have the permission
    const hasPermission = await this.askForPermission();
    if (!hasPermission) {
      console.log("no permission");
      return;
    } else {
      console.log("permission");
      // launch the camera with the following settings
      let image = await ImagePicker.launchCameraAsync({
        mediaTypes: ImagePicker.MediaTypeOptions.Images,
        allowsEditing: true,
        aspect: [3, 3],
        quality: 1,
        //base64: true,
      });
      console.log("image got");
      // make sure a image was taken:
      if (!image.cancelled) {
        console.log("image not canceled");
        console.log(image);
        this.handleChange(image);
      }
    }
  };
  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity
          style={{ justifyContent: "center", alignItems: "center" }}
          onPress={this.takeImage}
        >
          <Text
            style={{ alignSelf: "center", fontSize: 20, fontWeight: "bold" }}
          >
            Upload
          </Text>
        </TouchableOpacity>
        {this.state.image != null ? (
          <View
            style={{
              justifyContent: "center",
              alignItems: "center",
              alignSelf: "center",
              marginTop: "3em",
              height: "30%",
              width: "15%",
              borderWidth: 4,
              borderColor: "black",
            }}
          >
            <Image
              source={this.state.image}
              style={{width: "100%", height: "100%", alignSelf: "center"}}
            />
          </View>
        ) : null}
        <TouchableOpacity
          style={{
            width: "80%",
            height: "10%",
            alignSelf: "center",
            borderRadius: 8,
            borderWidth: 3,
            borderColor: "#000000",
            bottom: 20,
            position: "absolute",
            alignContent: "center",
            justifyContent: "center",
          }}
          onPress={() => {
            let result = editProfilePicture(this.state.image);
            result.then((res) => {
              if (res) {
                onPressHandler(
                  this.state.navigation,
                  "SuccessEdit",
                );
              }
            });
          }}
        >
          <Text style={{ alignSelf: "center", fontWeight: "bold" }}>
            Send the picture !
          </Text>
        </TouchableOpacity>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    flexDirection: "column",
  },
});

如您所见,当我们按下发送图片时,我们正在运行函数editProfilePicture:

export const editProfilePicture = async (uploaded_image) => {
  let form_data = new FormData();
  form_data.append("input_image", uploaded_image, "photo.jpg");
  try {
    let response = await fetch(
      "127.0.0.1:5000/change_profile_picture",
      {
        body: form_data,
        method: "put",
        credentials: "include",
      }
    );
    if (response.ok) {
      let json = await response.json();
      return true;
    } else {
      console.log("Not OK");
      return false;
    }
  } catch (error) {
    console.error(error);
    return false;
  }
};

请求被发送到 Flask 服务器,但在我的端点中,我在这一行遇到了 400 错误:

@auth.route("/change_profile_picture", methods=["PUT"])
@jwt_refresh_token_required
def change_profile_picture():
    """
    To do when the other endpoints work
    """
    input_image = request.files["input_image"]  # HERE !

结论:我认为问题出在我想发送图片的方式上。我该怎么做?我对 Blob、Canvas 等一无所知,所以欢迎使用一些代码行!

【问题讨论】:

  • 当你console.log(image);时,它会显示什么?
  • cancelled: false height: 960 uri: "data:image/jpeg;base64,/9j/4gIcSUNDX1BST0ZJTEUAAQE ....." width: 960 proto: Object I have感觉expo的这个功能不能在web设备上运行。 uri 不应该是 base64 值
  • 你尝试过这个问题的解决方案吗? stackoverflow.com/questions/42521679/…

标签: javascript reactjs react-native flask expo


【解决方案1】:

在 formdata apoend 文件中的选项中给出名称 src 并键入

【讨论】:

  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-07
  • 2021-07-30
  • 2018-03-28
  • 1970-01-01
  • 1970-01-01
  • 2020-04-23
  • 2020-06-30
相关资源
最近更新 更多