web-dev-qa-db-ja.com

React)のフォームデータを含む画像のアップロード

Reactアプリケーションで、いくつかのフォームデータとともに写真をアップロードしようとしています。これは、-の子コンポーネントであるItemAdd.jsxからのフォームデータのアップロードで機能します。 ItemList.jsx。ただし、このデータを含む画像ファイルもPOST)しようとすると、サーバーに到達したときの画像プロパティはundefinedになります。リクエストで間違ったコンテンツタイプを使用しているのではないかと疑っていますが、代わりに何を使用すべきかわかりません(それがここでの問題である場合)。

親コンポーネント-ItemList.jsx

import React from 'react';
import 'whatwg-fetch';
import classNames from 'classnames';
import ItemAdd from './ItemAdd.jsx';

export default class ItemList extends React.Component {
    constructor() {
        super();
        this.createItem = this.createItem.bind(this);
    }

    createItem(newItem) {
        console.log('PHOTO:', newItem.image);
        fetch('/api/item', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(newItem),
        }).then(response => {
        }).catch(err => {
        });
    }

    render() {
        return (
            <div>
                <ItemAdd createItem={this.createItem} />
            </div>
        );
    }
}

子コンポーネント-ItemAdd.jsx

import React from 'react';

export default class ItemAdd extends React.Component {

    constructor() {
        super();
        this.handleSubmit = this.handleSubmit.bind(this);
        this.state = {
            image: null,
            imagePreviewUrl: null
        }
    }

    handleSubmit(e) {
        e.preventDefault();
        let form = document.forms.itemAdd;
        this.props.createItem({
            name: form.name.value,
            image: this.state.image
        });
        // Clear the form and state for the next input.
        form.name.value = "";
        this.state.image = null;
        this.state.imagePreviewUrl = null;
    }

    handleImageChange(e) {
        e.preventDefault();

        let reader = new FileReader();
        let file = e.target.files[0];

        reader.onloadend = () => {
            this.setState({
                image: file,
                imagePreviewUrl: reader.result
            });
        }

        reader.readAsDataURL(file)
    }

    render() {
        let { imagePreviewUrl } = this.state;
        let $imagePreview = null;
        if (imagePreviewUrl) {
            $imagePreview = (<img src={imagePreviewUrl} className={'img-preview'} />);
        } else {
            $imagePreview = (<div className="previewText">Please select an image.</div>);
        }
        return (
            <div>
                <form name="itemAdd" onSubmit={this.handleSubmit}>
                    <table>
                        <tr>
                            <td><label for="name">Name:</label></td>
                            <td><input type="text" name="name" id="name" placeholder="Name" /></td>
                        </tr>
                        <tr>
                            <td><input type="file" onChange={(e) => this.handleImageChange(e)} /></td>
                            <td>
                                <div className="img-preview">
                                    {$imagePreview}
                                </div>
                            </td>
                        </tr>
                        <tr>
                            <td><button>Add</button></td>
                        </tr>
                    </table>
                </form>
            </div>
        );
    }
}
3
petehallw

JSONデータの一部として画像を投稿できない場合があります。画像でJSON.stringify()を呼び出すことはお勧めできません。 formDataを使用してフォームを送信することをお勧めします。これにより、フォームはmultipart/form-dataコンテンツタイプ。バックエンドで別の方法で処理する必要がある場合があります。

例:

createItem(newItem) {
    console.log('PHOTO:', newItem.image);
    const h = {}; //headers
    let data = new FormData();
    data.append('image', newItem.image);
    data.append('name', newItem.name);
    h.Accept = 'application/json'; //if you expect JSON response
    fetch(/api/item', {
      method: 'POST',
      headers: h,
      body: data
    }).then(response => {
    }).catch(err => {
    });p;
  } 

詳細については、formDataをご覧ください: https://developer.mozilla.org/en-US/docs/Web/API/FormData

1
Ankari