【问题标题】:React - 1st file upload to Spring API doesn't work, try again and it works fine on second try?React - 第一个文件上传到 Spring API 不起作用,再试一次,第二次尝试正常吗?
【发布时间】:2022-01-05 14:24:09
【问题描述】:

你好

我开发了一个前端 React 项目,它向 SpringBoot REST API 请求资源和逻辑。我最近实现了文件上传,我使用 React 创建的表单在第一次尝试时总是失败,但是当我再次单击它并上传不同的文件时(哪个文件无关紧要,不是文件造成的),它成功上传了通过 POST 使用二进制文件作为有效负载的文件。

第一个请求的负载为“未定义”。

反应形式:

const UPDATE_USER_URL = 'http://localhost:8080/users/update-user-details';
const UPLOAD_FILE_URL = 'http://localhost:8080/image-files';
class UpdateUserForm extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            username: localStorage.getItem("username"),
            location: "",
            bio: ""
        };
        this.onSubmit = this.onSubmit.bind(this);

        this.handleInputChange = this.handleInputChange.bind(this);
    }

    handleInputChange(event) {
        const target = event.target;
        const value = target.value;
        const name = target.name;

        this.setState({
            [name]: value
        });
    }

    onFileChangeHandler = (e) => {
        e.preventDefault();
        this.setState({
            selectedFile: e.target.files[0]
        });
        const formData = new FormData();
        formData.append('file', this.state.selectedFile);
        const USER_UPLOAD_FILE_URL = UPLOAD_FILE_URL + "/" + this.state.username;
        fetch(USER_UPLOAD_FILE_URL, {
            method: 'POST',
            headers: {
                "Authorization": localStorage.getItem("token")
            },
            body: formData
        }).then(res => {
            if(res.ok) {
                console.log(res.data);
                alert("File uploaded successfully.")
            }
        });

    };

    onSubmit(event) {
        event.preventDefault();
        const payload = {
            "username": this.state.username,
            "location": this.capital_letter(this.state.location),
            "bio": this.state.bio
        };

        fetch(UPDATE_USER_URL, {
            method: 'PUT',
            headers: {
                "Accept": "application/json",
                "Content-Type": "application/json",
                "Authorization": localStorage.getItem("token")
            },
            body: JSON.stringify(payload)
        })
            .then(response => response.json())
            .then((data) => {
                console.log(data);
            });
    }
    //https://www.w3resource.com/javascript-exercises/javascript-basic-exercise-50.php
    capital_letter(str) {

        str = str.split(" ");

        for (var i = 0, x = str.length; i < x; i++) {
            str[i] = str[i][0].toUpperCase() + str[i].substr(1);
        }
        console.log(str)
        return str.join(" ");
    }

    generateUploadUrl(username) {

    }

    render() {
        return (
            <div className="outer-div-container">
                <div>
            <AppNavbar/>
            <div id="form-container">
                <div id="form-div">

                    <h5 id="form-heading">Update Details</h5>
                    <br />
            <div className="outer-div-container">
            <form onSubmit={this.onSubmit}>
                <label className="form-label" id="top-form-label">
                    Location:
                    <br />
                    <input
                        className="form-input"
                        //Taumatawhakatangihangakoauauotamateaturipukakapikimaungahoronukupokaiwhen
                        maxLength="85"
                        //No min length as places with 1 letter e.g: A, S.
                        name="location"
                        type="text"
                        value={this.state.location}
                        onChange={this.handleInputChange} />
                </label>
                <br />
                <label className="form-label">
                    Bio:
                    <br />
                    <input
                        className="form-input"
                        minLength="3"
                        name="bio"
                        type="text"
                        value={this.state.bio}
                        onChange={this.handleInputChange} />
                </label>
                <label>Upload Your File </label>
                <input type="file" className="form-control" name="file" onChange={this.onFileChangeHandler}/>

                <br />
                <input id="form-submit" type="submit" value="Submit" />

            </form>
                <div className="form-group files color">
                        <label>Upload Your File </label>
                        <input type="file" className="form-control" name="file" onChange={this.onFileChangeHandler}/>
                </div>
            </div>
            </div>
                </div>
            </div>
            </div>
        );
    }
}
export default UpdateUserForm;

控制器:

@RestController
@RequestMapping("image-files")
@AllArgsConstructor
@CrossOrigin("*")
public class ImageFileController {
    ImageFileService service;


    @GetMapping(value = "/{username}")
    public byte[] downloadImageFile(@PathVariable String username) {
        return service.downloadImageFile(username);
    }
}

任何帮助将不胜感激,我完全被难住了,谢谢。

【问题讨论】:

    标签: javascript java reactjs spring-boot upload


    【解决方案1】:

    在您的 onFileChangeHandler 函数中,您将文件设置为 selectedFile 状态,然后立即再次访问它

    formData.append('file', this.state.selectedFile);
    

    您不能将某些内容设置为 react 状态并在下一行再次访问它,这是因为 setState 在 react 中异步工作。这意味着如果你想从反应状态中获取最新的设置值,你需要等待下一次重新渲染发生。否则,您将只能从状态中获取先前设置的值,在您的情况下为 undefined。所以在你的函数中,将文件数据直接传递给formData。试试下面的代码

    onFileChangeHandler = (e) => {
        e.preventDefault();
        const fileData = e.target.files[0];
        this.setState({
            selectedFile: fileData
        });
        const formData = new FormData();
        formData.append('file', fileData);
        const USER_UPLOAD_FILE_URL = UPLOAD_FILE_URL + "/" + this.state.username;
        fetch(USER_UPLOAD_FILE_URL, {
            method: 'POST',
            headers: {
                "Authorization": localStorage.getItem("token")
            },
            body: formData
        }).then(res => {
            if(res.ok) {
                console.log(res.data);
                alert("File uploaded successfully.")
            }
        });
    
    };
    

    【讨论】:

    • 非常感谢,这个解释很好,代码运行良好!
    • 乐于助人:)
    猜你喜欢
    • 2016-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-15
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多