web-dev-qa-db-ja.com

React.js、multipart / form-dataをサーバーに送信する方法

画像ファイルをmultipart/formとしてバックエンドに送信します。htmlフォームを使用してファイルを取得し、ファイルをformDataとして送信します。コードは次のとおりです。

export default class Task extends React.Component {

  uploadAction() {
    var data = new FormData();
    var imagedata = document.querySelector('input[type="file"]').files[0];
    data.append("data", imagedata);

    fetch("http://localhost:8910/taskCreationController/createStoryTask", {
      mode: 'no-cors',
      method: "POST",
      headers: {
        "Content-Type": "multipart/form-data"
        "Accept": "application/json",
        "type": "formData"
      },
      body: data
    }).then(function (res) {
      if (res.ok) {
        alert("Perfect! ");
      } else if (res.status == 401) {
        alert("Oops! ");
      }
    }, function (e) {
      alert("Error submitting form!");
    });
  }

  render() {
    return (
        <form encType="multipart/form-data" action="">
          <input type="file" name="fileName" defaultValue="fileName"></input>
          <input type="button" value="upload" onClick={this.uploadAction.bind(this)}></input>
        </form>
    )
  }
}

バックエンドのエラーはです。ネストされた例外はorg.springframework.web.multipart.MultipartException:マルチパートサーブレットリクエストを解析できませんでした。ネストされた例外はJava.io.IOException:org.Apache.Tomcatです。 util.http.fileupload.FileUploadException:マルチパート境界が見つからなかったため、要求は拒否されました。」

this を読んだ後、フェッチでヘッダーに境界を設定しようとしました:

fetch("http://localhost:8910/taskCreationController/createStoryTask", {
      mode: 'no-cors',
      method: "POST",
      headers: {
        "Content-Type": "multipart/form-data; boundary=AaB03x" +
        "--AaB03x" +
        "Content-Disposition: file" +
        "Content-Type: png" +
        "Content-Transfer-Encoding: binary" +
        "...data... " +
        "--AaB03x--",
        "Accept": "application/json",
        "type": "formData"
      },
      body: data
    }).then(function (res) {
      if (res.ok) {
        alert("Perfect! ");
      } else if (res.status == 401) {
        alert("Oops! ");
      }
    }, function (e) {
      alert("Error submitting form!");
    });
  }

今回は、バックエンドのエラーは次のとおりです。サーブレット[dispatcherServlet]のServlet.service()は、コンテキスト[パス[]で例外をスロー[要求処理に失敗しました。ネストされた例外は、根本原因のJava.lang.NullPointerException]です。

マルチパート境界を正しく追加しますか?どこにあるべきですか? multipart/form-dataを取得しないため、最初は間違っているのかもしれません。どうすれば正しく取得できますか?

13
Peter Jiang

ヘッダーを削除しようとすると、機能します!

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!");
    });
9
Peter Jiang

このファイルは、イベントでも利用できます。

_e.target.files[0]
_

document.querySelector('input[type="file"]').files[0];の必要性を排除します)

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

注:デバッグにconsole.log(data.get('inputname'))を使用すると、console.log(data)は追加されたデータを表示しません。

2
Jerimiah Mair

React File Uploadコンポーネント

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
vinfinit