首页 > 解决方案 > 在 React Js 中处理多个上传图像 + 将其发送到服务器

问题描述

今天我上传图片时遇到了一些问题。我尝试从前端上传 2 张图片,但在后端出现错误Error can't sent Header after they sent。当我只上传 1 张图片时,我没有收到错误,但是当我尝试上传 2 张图片时,我收到了错误。我需要做什么?我应该使用多部分/表单数据吗?

我尝试使用 multipart/form-data 但它不起作用

import {Link} from 'react-router-dom'

class Category extends React.Component{
    constructor(props){
        super(props);

        this.state={
            categoryId : this.props.match.params.id,
            dataCategory:[],
            categoryName:"",
            categoryDesc:"",
            categoryImage:"",
            categoryImageCabor:"",
            namaCabor :"",
            descCabor :"",
            imgCabor :"",
            imageCabor : "",
            selectedFile: null,
            imagePreviewUrl :"",
            file:""
        }
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleChange = this.handleChange.bind(this);
        this.imageHandleChange = this.imageHandleChange.bind(this);
    }
    componentWillMount(){
        this.getDetailsData();
    }

    getDetailsData(i){
        let categoryId = this.state.categoryId;

        fetch(`http://localhost:4000/get/${categoryId}`).then(res =>{
            if(res.status === 200)
                return res.json().then(resCategoryId =>{
                    console.log(resCategoryId);
                    this.setState({
                        id : resCategoryId._id,
                        namaCabor : resCategoryId.namaCabor,
                        descCabor : resCategoryId.descCabor,
                        imgCabor : resCategoryId.imgCabor,
                        imageCabor : resCategoryId.imageCabor
                    });
                });
            }).catch(err =>{
                if(err) console.log(err);
            })
    }


    imageHandleChange(e){
        e.preventDefault();

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

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


    handleSubmit(e){
        e.preventDefault();
        let {imagePreviewUrl} = this.state;
        const dataCategory = this.state.dataCategory;
        let categoryName = this.refs.categoryName.value;
        let categoryImage = this.refs.categoryImage.value;
        let categoryDesc =  this.refs.categoryDesc.value,
            categoryImageCabor = (<img alt="www.google.com" height="100px" src={imagePreviewUrl} />),
            namaCabor = this.refs.namaCabor.value,
            descCabor = this.refs.descCabor.value,
            imageCabor = (<img height="100px" src={this.state.imageCabor.props.src} />)

            fetch('http://localhost:4000/add', {
                mode:'cors',
                method:'post',
                headers:{
                    'Content-Type' : 'application/json',
                    "Accept" : "application/json",
                    "type" : "formData"
                },
                body:JSON.stringify({
                    categoryName : categoryName,
                    categoryDesc : categoryDesc,
                    categoryImage: categoryImage,
                    categoryImageCabor : categoryImageCabor,
                    namaCabor : namaCabor,
                    descCabor : descCabor,
                    imageCabor : imageCabor,
                    status : true
                }),
            }).then(res=>{
                return res.json();
            }).catch(function(err){
                if(err){
                    console.log(err);
                }
            })

        this.setState({
            dataCategory : dataCategory,
            imagePreviewUrl : false,
        });
        this.refs.myForm.reset();
        this.refs.myForm.focus();
    }
    handleChange(e){
        this.setState({
            [e.target.categoryName] : e.target.value,
            [e.target.categoryImage] : e.target.value,
            [e.target.categoryDesc] : e.target.value
        })
    }

    render(){

        let {imagePreviewUrl} = this.state;
        let $imagePreview = null;

        if(imagePreviewUrl){
            $imagePreview = (<img alt ="www.google.com" height="100px" src={imagePreviewUrl} />)
        }

        return this.state.imageCabor === "" ? <div></div> : (
            <div>
                <h3>Insert Category Cabang Olahraga </h3>
                <form style={{marginTop: 10}} ref="myForm" onSubmit={this.handleSubmit} encType="multipart/form-data" >
                    <div className="form-group">
                        <label>Nama Category</label>
                        <input
                            name="categoryName"
                            type="text"
                            className="form-control"
                            ref="categoryName"
                            onChange={this.handleChange}               
                        />
                        </div>

                        <div className="form-group">
                        <label>Deskripsi Category </label>
                        <textarea

                            name="categoryDesc"
                            type="text"
                            className="form-control"
                            ref="categoryDesc"
                            rows="5"
                            onChange={this.handleChange}
                        />
                        </div>

                        <div className="form-group">
                            <label>Upload Icon Image</label> <br />
                            <div>{$imagePreview}</div>
                        <input
                            name="categoryImage"
                            type="file"
                            ref="categoryImage"
                            className="image-control"
                            onChange={this.imageHandleChange}
                            />
                        </div>

                        <h1>Cabang Olahraga</h1>
                        <div className ="form-group">
                            <label>Nama Cabang Olahraga</label>
                        <input 
                            name="namaCabor"
                            type="text"
                            className="form-control"
                            ref="namaCabor"
                            value={this.state.namaCabor}
                            />
                        </div>

                        <div className ="form-group">
                            <label>Deskripsi Cabang Olahraga</label>
                        <textarea
                            name="descCabor"
                            type="text"
                            className="form-control"
                            ref="descCabor"
                            rows="5"
                            value={this.state.descCabor}
                            />
                        </div>

                        <div className="form-group">
                            <label>Icon Cabang Olahraga</label> <br />
                            <div><img height="100px" src={this.state.imageCabor.props.src} /></div>
                        </div>

                        <div className="form-group">
                            <input type="submit" value="Apply" className ="btn btn-primary" />
                        </div>

                </form>
            </div>
        );
    }
}

export default Category;

在我的后端得到了输出。发送后无法设置标头错误。

标签: javascriptnode.jsreactjsmongodbecmascript-6

解决方案


您需要使用类似这样的 FormData 将 formData 提交到服务器

var formData = new FormData();
for (const file of this.state.files) {
  formData.append('file', file)
  formData.append('file2', file2)
  formData.append('file3', file3)
}

或者你可以用简单的方式写

var formData = new FormData();
formData.append('file', file)
formData.append('file2', file2)
formData.append('file3', file3)

请根据您的代码进行相应更改

确保将标题设置multipart/form-data

干杯


推荐阅读