React.js, how to send a multipart/form-data to server

前端 未结 6 1012
走了就别回头了
走了就别回头了 2020-12-14 01:35

We want to send an image file as multipart/form to the backend, we try to use html form to get file and send the file as formData, here are the codes

export          


        
相关标签:
6条回答
  • 2020-12-14 02:22

    For sending multipart/formdata, you need to avoid contentType, since the browser automatically assigns the boundary and Content-Type.

    In your case by using fetch, even if you avoid Content-Type it sets to default text/plain. So try with jQuery ajax. which removes the contentType if we set it to false.

    This is the working code

    var data = new FormData();
    var imagedata = document.querySelector('input[type="file"]').files[0];
    data.append("data", imagedata);
    $.ajax({
        method: "POST",
        url: fullUrl,
        data: data,
        dataType: 'json',
        cache: false,
        processData: false,
        contentType: false
    }).done((data) => {
        //resolve(data);
    }).fail((err) => {
        //console.log("errorrr for file upload", err);
        //reject(err);
    });
    
    0 讨论(0)
  • 2020-12-14 02:28

    Here is my solution for image upload with preview through axios.

    import React, { Component } from 'react';
    import axios from "axios";
    

    React Component Class:

    class FileUpload extends Component {
    
        // API Endpoints
        custom_file_upload_url = `YOUR_API_ENDPOINT_SHOULD_GOES_HERE`;
    
    
        constructor(props) {
            super(props);
            this.state = {
                image_file: null,
                image_preview: '',
            }
        }
    
        // Image Preview Handler
        handleImagePreview = (e) => {
            let image_as_base64 = URL.createObjectURL(e.target.files[0])
            let image_as_files = e.target.files[0];
    
            this.setState({
                image_preview: image_as_base64,
                image_file: image_as_files,
            })
        }
    
        // Image/File Submit Handler
        handleSubmitFile = () => {
    
            if (this.state.image_file !== null){
    
                let formData = new FormData();
                formData.append('customFile', this.state.image_file);
                // the image field name should be similar to your api endpoint field name
                // in my case here the field name is customFile
    
                axios.post(
                    this.custom_file_upload_url,
                    formData,
                    {
                        headers: {
                            "Authorization": "YOUR_API_AUTHORIZATION_KEY_SHOULD_GOES_HERE_IF_HAVE",
                            "Content-type": "multipart/form-data",
                        },                    
                    }
                )
                .then(res => {
                    console.log(`Success` + res.data);
                })
                .catch(err => {
                    console.log(err);
                })
            }
        }
    
    
        // render from here
        render() { 
            return (
                <div>
                    {/* image preview */}
                    <img src={this.state.image_preview} alt="image preview"/>
    
                    {/* image input field */}
                    <input
                        type="file"
                        onChange={this.handleImagePreview}
                    />
                    <label>Upload file</label>
                    <input type="submit" onClick={this.handleSubmitFile} value="Submit"/>
                </div>
            );
        }
    }
    
    export default FileUpload;
    
    0 讨论(0)
  • 2020-12-14 02:29

    https://muffinman.io/uploading-files-using-fetch-multipart-form-data/ worked best for me. Its using formData.

    import React from "react";
    import logo from "./logo.svg";
    import "./App.css";
    import "bootstrap/dist/css/bootstrap.min.css";
    import Button from "react-bootstrap/Button";
    
    const ReactDOM = require("react-dom");
    
    
    export default class App extends React.Component {
      constructor(props) {
        super(props);
        this.test = this.test.bind(this);
        this.state = {
          fileUploadOngoing: false
        };
      }
    
      test() {
        console.log(
          "Test this.state.fileUploadOngoing=" + this.state.fileUploadOngoing
        );
        this.setState({
          fileUploadOngoing: true
        });
    
        const fileInput = document.querySelector("#fileInput");
        const formData = new FormData();
    
        formData.append("file", fileInput.files[0]);
        formData.append("test", "StringValueTest");
    
        const options = {
          method: "POST",
          body: formData
          // If you add this, upload won't work
          // headers: {
          //   'Content-Type': 'multipart/form-data',
          // }
        };
        fetch("http://localhost:5000/ui/upload/file", options);
      }
      render() {
        console.log("this.state.fileUploadOngoing=" + this.state.fileUploadOngoing);
        return (
          <div>
            <input id="fileInput" type="file" name="file" />
            <Button onClick={this.test} variant="primary">
              Primary
            </Button>
    
            {this.state.fileUploadOngoing && (
              <div>
                <h1> File upload ongoing abc 123</h1>
                {console.log(
                  "Why is it printing this.state.fileUploadOngoing=" +
                    this.state.fileUploadOngoing
                )}
              </div>
            )}
    
          </div>
        );
      }
    }
    
    0 讨论(0)
  • 2020-12-14 02:30

    The file is also available in the event:

    e.target.files[0]
    

    (eliminates the need for document.querySelector('input[type="file"]').files[0];)

    uploadAction(e) {
      const data = new FormData();
      const imagedata = e.target.files[0];
      data.append('inputname', imagedata);
      ...
    

    Note: Use console.log(data.get('inputname')) for debugging, console.log(data) will not display the appended data.

    0 讨论(0)
  • 2020-12-14 02:31

    React File Upload Component

    import { Component } from 'react';
    
    class Upload extends Component {
      constructor() {
        super();
        this.state = {
          image: '',
        }
      }
    
      handleFileChange = e => {
        this.setState({
          [e.target.name]: e.target.files[0],
        })
      }
    
      handleSubmit = async e => {
        e.preventDefault();
    
        const formData = new FormData();
        for (let name in this.state) {
          formData.append(name, this.state[name]);
        }
    
        await fetch('/api/upload', {
          method: 'POST',
          body: formData,
        });
    
        alert('done');
      }
    
      render() {
        return (
          <form onSubmit={this.handleSubmit}>
            <input 
              name="image" 
              type="file"
              onChange={this.handleFileChange}>
            </input>
            <input type="submit"></input>
          </form>
        )
      }
    }
    
    export default Upload;
    
    0 讨论(0)
  • 2020-12-14 02:37

    We just try to remove our headers and it works!

    fetch("http://localhost:8910/taskCreationController/createStoryTask", {
          mode: 'no-cors',
          method: "POST",
          body: data
        }).then(function (res) {
          if (res.ok) {
            alert("Perfect! ");
          } else if (res.status == 401) {
            alert("Oops! ");
          }
        }, function (e) {
          alert("Error submitting form!");
        });
    
    0 讨论(0)
提交回复
热议问题