在 React 中使用表单数据上传图像

Uploading image with form data in 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>
        );
    }
}

您可能无法 post 图像作为 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 => {
        // TODO : Do something
    }).catch(err => {
        // TODO : Do something
    });
  }

您可以在 formData

上阅读更多内容