在 React 中上传带有表单数据的图像

Posted

技术标签:

【中文标题】在 React 中上传带有表单数据的图像【英文标题】:Uploading image with form data in React 【发布时间】:2018-09-03 03:58:22 【问题描述】:

我正在尝试在我的 React 应用程序中上传一张照片以及一些表单数据。它适用于从 ItemAdd.jsxItemList.jsx 的子组件)上传表单数据。但是,当我尝试使用此数据发布图像文件时,图像属性在到达服务器时为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>
        );
    

【问题讨论】:

【参考方案1】:

您可能无法将图像作为 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上阅读更多内容

【讨论】:

以上是关于在 React 中上传带有表单数据的图像的主要内容,如果未能解决你的问题,请参考以下文章

带有 MultiPart 表单数据中的参数的图像上传在 Alamofire 4.0 中不起作用

必须使用 HttpClient C# 上传带有注册表单数据的图像

使用 PHP yii 框架以带有图像预览和裁剪工具的注册表单上传图像?

请求参数为空,在提交带有图像的表单数据 AJAX 后

react + spring boot 上传文件和表单数据

在 Flutter 中上传带有 http.post 和注册表单的图像?