REACT TypeError:无法在'FormData'上执行'append':参数2不是'Blob'类型

时间:2020-02-16 12:51:15

标签: javascript reactjs

嗨,我在React中注册新用户时遇到此错误问题。您知道如何解决吗?我像99,9%的肯定我正在将blob对象发送到data.append:(

这是我有状态并将所有数据发送到API时的第一个文件

import React, { Component } from "react";
import FormUserDetailsStep1 from "../register-form/Register-step-1";
import FormUserDetailsStep2 from "../register-form/Register-step-2";
import FormUserDetailsStep3 from "../register-form/Register-step-3";
import FormUserDetailsStep4 from "../register-form/Register-step-4";
import FormUserDetailsStep5 from "../register-form/Register-step-5";
import FormUserDetailsStep6 from "../register-form/Register-step-6";
import FormUserDetailsStep7 from "../register-form/Register-step-7";
import axios from "axios";
import { Route, Redirect } from "react-router";

/* eslint-disable */

class RegForm extends Component {
  state = {
    step: 1,
    country: "",
    countrySelected: "",
    city: [],
    citySelected: "",
    namePrivate: "",
    namePublic: "",
    email: "",
    socialMediaFb: "",
    socialMediaInsta: "",
    socialMediaYt: "",
    ProfileImage: '' ,
    description: ``,
    category: [],
    budget: 400,
    password: "",
    passwordRepeat: "",
    imgValue: "",
  }

  // Proceed to next step
  nextStep = () => {
    const { step } = this.state;
    this.setState({
      step: step + 1
    });
  };

  prevStep = () => {
    const { step } = this.state;
    this.setState({
      step: step - 1
    });
  };

  changeHandler = e => {
    this.setState({ [e.target.name]: e.target.value });
  };

  changeCountryHandler = e => {
    const city_id = e.value;
    axios
      .get("https://backend.showgo.tech/api/cities/" + city_id)
      .then(response => {
        this.setState({
          city: response.data,
          countrySelected: e.value
        });
      });
  };

  changeCityHandler = e => {
    this.setState({
      citySelected: e.value
    });
  };

  budgetHandler = e => {
    let budget = e;
    this.setState({
      budget: budget
    });
  };

  budgetAfterHandler = e => {
    let budget = e;
    this.setState({
      budget: budget
    });
  };

  categoryHandler = e => {
    this.setState({
      category: e.value
    });
  };

  blobHandler = e => {

  const blobImage = URL.createObjectURL(e)

  this.setState({
  imgValue: blobImage
  })

  console.log("AAAblob", blobImage)

  console.log("BLOBSTATE", this.state.imgValue )

    };



  buildFormData(formData, data, parentKey) {
    if (
      data &&
      typeof data === "object" &&
      !(data instanceof Date) &&
      !(data instanceof File)
    ) {
      Object.keys(data).forEach(key => {
        this.buildFormData(
          formData,
          data[key],
          parentKey ? `${parentKey}[${key}]` : key
        );
      });
    } else {
      const value = data == null ? "" : data;
      formData.append(parentKey, value);
    }
  }

  submitHandler = e => {
    e.preventDefault();
    let data = new FormData();
    this.buildFormData(data, this.state.country, "country");
    this.buildFormData(data, this.state.countrySelected, "countrySelected");
    this.buildFormData(data, this.state.city, "city");
    this.buildFormData(data, this.state.citySelected, "citySelected");
    this.buildFormData(data, this.state.namePrivate, "namePrivate");
    this.buildFormData(data, this.state.namePublic, "namePublic");
    this.buildFormData(data, this.state.email, "email");
    this.buildFormData(data, this.state.socialMediaFb, "socialMediaFb");
    this.buildFormData(data, this.state.socialMediaInsta, "socialMediaInsta");
    this.buildFormData(data, this.state.socialMediaYt, "socialMediaYt");
    //this.buildFormData(data,this.state.ProfileImage,'ProfileImage')
    this.buildFormData(data, this.state.description, "description");
    this.buildFormData(data, this.state.category, "category");
    this.buildFormData(data, this.state.budget, "budget");
    this.buildFormData(data, this.state.password, "password");
    this.buildFormData(data, this.state.passwordRepeat, "passwordRepeat");

    data.append("file", this.state.imgValue, "photo.jpg");
    const URL = "https://backend.showgo.tech/api/auth/register";
    let config = {
      headers: {
        "Content-Type": "multipart/form-data"
      }
    };
    axios.post(URL, data, config).then(response => {
      this.props.history.push("/create-profile");
    });
  };

  render() {



    const { step } = this.state;

    const {
      country,
      countrySelected,
      city,
      citySelected,
      namePrivate,
      namePublic,
      email,
      socialMediaFb,
      socialMediaInsta,
      socialMediaYt,
      image,
      ProfileImage,
      description,
      category,
      budget,
      password,
      passwordRepeat,
      blobHandler,
      imgValue,
      PasswordMessage

    } = this.state;

    const values = {
      country,
      countrySelected,
      city,
      citySelected,
      namePrivate,
      namePublic,
      email,
      socialMediaFb,
      socialMediaInsta,
      socialMediaYt,
      image,
      description,
      category,
      budget,
      password,
      passwordRepeat,
      ProfileImage,
      blobHandler,
      imgValue,
      PasswordMessage
    };

    switch (step) {
      case 1:
        return (
          <FormUserDetailsStep1
            nextStep={this.nextStep}
            changeHandler={this.changeHandler}
            changeCountryHandler={this.changeCountryHandler}
            changeCityHandler={this.changeCityHandler}
            values={values}
            countryApi={this.countryApi}
          />
        );

      case 2:
        return (
          <FormUserDetailsStep2
            nextStep={this.nextStep}
            prevStep={this.prevStep}
            changeHandler={this.changeHandler}
            values={values}
          />
        );

      case 3:
        return (
          <FormUserDetailsStep3
            nextStep={this.nextStep}
            prevStep={this.prevStep}
            changeHandler={this.changeHandler}
            blobHandler={this.blobHandler}
            values={values}
          />
        );

      case 4:
        return (
          <FormUserDetailsStep4
            nextStep={this.nextStep}
            prevStep={this.prevStep}
            changeHandler={this.changeHandler}
            categoryHandler={this.categoryHandler}
            values={values}
          />
        );

      case 5:
        return (
          <FormUserDetailsStep5
            nextStep={this.nextStep}
            prevStep={this.prevStep}
            changeHandler={this.changeHandler}
            budgetHandler={this.budgetHandler}
            budgetAfterHandler={this.budgetAfterHandler}
            values={values}
          />
        );

        case 6:
          return (
            <FormUserDetailsStep6
              nextStep={this.nextStep}
              prevStep={this.prevStep}
              changeHandler={this.changeHandler}
              budgetHandler={this.budgetHandler}
              budgetAfterHandler={this.budgetAfterHandler}
              values={values}
            />
          );

      case 7:
        return (
          <FormUserDetailsStep7
            nextStep={this.nextStep}
            prevStep={this.prevStep}
            changeHandler={this.changeHandler}
            values={values}
            submitHandler={this.submitHandler}
            blobHandler = {this.blobHandler}
          />
        );

      case 8:
        return <h1>Thanks</h1>;
    }
  }
}
export default RegForm;

这是我添加图片,裁剪图片并生成blob对象时的第二个文件

import React, { Component } from "react";
import { Helmet } from "react-helmet";
import Dropzone from "react-dropzone";
import ReactCrop from "react-image-crop";
import "../../App.css";
import "./Custom-crop-image.css";
import Footer from "../../Footer"
/* eslint-disable */

import {
  base64StringtoFile,
  downloadBase64File,
  extractImageFileExtensionFromBase64,
  image64toCanvasRef
} from "./ResuableUtils";

const imageMaxSize = 13000000; // bytes
const acceptedFileTypes =
  "image/x-png, image/png, image/jpg, image/jpeg, image/gif";
const acceptedFileTypesArray = acceptedFileTypes.split(",").map(item => {
  return item.trim();
});

class RegisterStep3 extends Component {
  constructor(props) {
    super(props);
    this.imagePreviewCanvasRef = React.createRef();
    this.fileInputRef = React.createRef();
    this.state = {
      imgSrc: null,
      imgSrcExt: null,
      imageVal: "",
      imageVal2: "",
      crop:  {x: 25, y: 20, width: 45.75, height: 54.95495495495496, aspect: 1/1},

    };
  }

  componentDidMount() {
    window.scrollTo(0, 0)
  }

  verifyFile = files => {
    if (files && files.length > 0) {
      const currentFile = files[0];
      const currentFileType = currentFile.type;
      const currentFileSize = currentFile.size;
      if (currentFileSize > imageMaxSize) {
        alert(
          "This file is not allowed. " + currentFileSize + " bytes is too large"
        );
        return false;
      }
      if (!acceptedFileTypesArray.includes(currentFileType)) {
        alert("This file is not allowed. Only images are allowed.");
        return false;
      }
      return true;
    }
  };

  handleOnDrop = (files, rejectedFiles) => {



    if (rejectedFiles && rejectedFiles.length > 0) {
      this.verifyFile(rejectedFiles);
    }

    if (files && files.length > 0) {
      const isVerified = this.verifyFile(files);
      if (isVerified) {
        // imageBase64Data
        const currentFile = files[0];
        const myFileItemReader = new FileReader();
        myFileItemReader.addEventListener(
          "load",
          () => {
            const myResult = myFileItemReader.result;
            this.setState({
              imgSrc: myResult,
              imgSrcExt: extractImageFileExtensionFromBase64(myResult)
            });
          },
          false
        );

        myFileItemReader.readAsDataURL(currentFile);
      }
    }
  };

  handleOnCropChange = crop => {
 // not this one
    this.setState({ crop: crop });
  };



  handleOnCropComplete = (crop, pixelCrop) => {

   const canvasRef = this.imagePreviewCanvasRef.current;

   const { imgSrc } = this.state;


    canvasRef.toBlob((blob) => {
      //Generate random string
      let randomString = Math.random().toString(36).substring(7);

       blob.name = randomString;

       this.props.blobHandler(blob)

      // values.ProfileImage = blob
     }, 'image/jpeg', 1);

     image64toCanvasRef(canvasRef, imgSrc, pixelCrop);


  };


  handleDownloadClick = event => {
    event.preventDefault();
    const { imgSrc } = this.state;
    if (imgSrc) {
      const canvasRef = this.imagePreviewCanvasRef.current;

      const { imgSrcExt } = this.state;
      const imageData64 = canvasRef.toDataURL("image/" + imgSrcExt);

      const myFilename = "previewFile." + imgSrcExt;

      // file to be uploaded
      const myNewCroppedFile = base64StringtoFile(imageData64, myFilename);
      // download file
      downloadBase64File(imageData64, myFilename);
      this.handleClearToDefault();
    }
  };

  handleClearToDefault = event => {
    if (event) event.preventDefault();
    const canvas = this.imagePreviewCanvasRef.current;
    const ctx = canvas.getContext("2d");
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    this.setState({
      imgSrc: null,
      imgSrcExt: null,
      crop: {
        aspect: 1 / 1
      }
    });
    this.fileInputRef.current.value = null;
  };

  handleFileSelect = event => {



    const files = event.target.files;
    if (files && files.length > 0) {
      const isVerified = this.verifyFile(files);
      if (isVerified) {
        // imageBase64Data
        const currentFile = files[0];
        const myFileItemReader = new FileReader();
        myFileItemReader.addEventListener(
          "load",
          () => {
            const myResult = myFileItemReader.result;
            this.setState({
              imgSrc: myResult,
              imgSrcExt: extractImageFileExtensionFromBase64(myResult)
            });
          },
          false
        );

        myFileItemReader.readAsDataURL(currentFile);
      }
    }

  };

  //My code



  continue = e => {
    e.preventDefault();


      this.props.nextStep();

  };

  goBack = e => {
    e.preventDefault();
    this.props.prevStep();
  };



  render() {




    const imageValidation = this.state.imageVal
    const imageValidation2 = this.state.imageVal2
    const { values, changeHandler, blobHandler } = this.props;
    const { imgSrc } = this.state;

    const inputStyle = {
      border: "1px dashed",
      borderWidth: "2px",
      borderColor: "#f0c527",
      margin: "20px 0"
    };

    const dragAndDropStyle = {
      border: "1px dashed",
      borderWidth: "2px",
      borderColor: "#f0c527",
      padding: "5px",
      margin: "20px 0",
      height: "200px",
      width: "100%"
    };

    const canvasStyle = {
      backgroundColor: "white",
      width: "50vw",
      maxWidth: "400px",
    }

    console.log("crop: " , this.state.crop)



    return (
      <>
        <Helmet>
        <title> Showgo Register // 3 Step</title>
          <meta content={4} property="og:title" />
          <meta content="width=device-width, initial-scale=1" name="viewport" />
          <link href="../css/normalize.css" rel="stylesheet" type="text/css" />
          <link href="../css/custom.css" rel="stylesheet" type="text/css" />
          <link href="../css/showgo.css" rel="stylesheet" type="text/css" />
          {/* [if lt IE 9]>
            <![endif] */}
          <link
            href="icons/favicon.ico"
            rel="shortcut icon"
            type="image/x-icon"
          />
          <link href="icons/webclip.png" rel="apple-touch-icon" />
        </Helmet>

        <h1>{values.ProfileImage}</h1>

        <div className="container-4 nav2bg w-container">
          <div>
            <img
              src="../images/Path_31.png"
              alt
              className="image-4 image-6"
              onClick={this.goBack}
            />
          </div>
        </div>
        <div>
          <div className="div-block-30">
            <img src="../images/camera.png" alt className="image-14" />
          </div>
          <div>
            <div className="bigfonttitle">Lägg upp dina bilder !</div>
            <div className="div-block-31">
              <div className="text-block-16">
                En profilbild krävs för att din profil skal visas och <br />
                bli bokbar för besökare!
              </div>
            </div>
          </div>

          <form onSubmit={this.continue} className="form-3a">
            <div className="div-block-32">
              <input
                style={inputStyle}
                ref={this.fileInputRef}
                type="file"
                accept={acceptedFileTypes}
                multiple={true}
                onChange={this.handleFileSelect}
              />


              {imgSrc !== null ? (


                <div>
                  <ReactCrop
                    src={imgSrc}
                    crop={this.state.crop}
                    onImageLoaded={this.handleImageLoaded}
                    onComplete={this.handleOnCropComplete}
                    onChange={this.handleOnCropChange}
                  />


                  <br />
                  <h3>Förhandsgranskning</h3>

                  <canvas ref={this.imagePreviewCanvasRef} style={canvasStyle} ></canvas>

                  <br></br>
                  <button onClick={this.handleDownloadClick}>Ladda ner </button>
                  <button onClick={this.handleClearToDefault}> Rensa</button>
                </div>
              ) : 

              (
                <>
                  <Dropzone
                    onDrop={this.handleOnDrop}
                    accept={acceptedFileTypes}
                    multiple={false}
                    maxSize={imageMaxSize}
                    style={dragAndDropStyle}
                    className="dropzone"
                  >
                    Släpp bilden här eller klicka för att ladda upp
                  </Dropzone>


                </>
              )}

            </div>
            <h3 style={{color:"red"}}>{imageValidation}</h3>
            <h3 style={{color:"red"}}>{imageValidation2}</h3>


            <div className="div-block-34">
              <button type="submit" className="button-2 gold-design w-button">
                Fortsätt 
              </button>
            </div>
          </form>
        </div>


        <Footer/>
      </>
    );
  }
}

export default RegisterStep3;

0 个答案:

没有答案