页面加载图像似乎已损坏,但随后加载

时间:2018-06-22 20:53:30

标签: reactjs amazon-s3

我正在使用AWS S3存储桶将用户选择用来更改其个人资料图片的图像存储在S3存储桶中。我可以使用该功能来更新照片,但是,我注意到,刷新页面几秒钟后,图像显示为瞬间破裂,然后加载到页面上。

我的假设是在页面加载时,API还没有时间获取图像数据,因此我研究了React的代码拆分并尝试了基于Route的拆分,但是仍然遇到问题:

此外,当我也从页面导航到控制台中的另一个页面时,我得到以下消息:https://awss3link/blah-blah-blah/undefined 404 (Not Found),即使我在应用程序中声明了附加在链接上的变量,并且图像也正确显示在页面上?

如果需要,我还可以在我的routes.js文件中包含我使用基于路由的拆分的代码。

这是我的代码:

import React from 'react';
import Header from '../common/Header';
import { Modal, Button } from 'react-bootstrap';
import {Redirect} from 'react-router-dom';
import profileService from '../../services/Profilepage';

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

        this.handleClose = this.handleClose.bind(this);
        this.handleShow = this.handleShow.bind(this);

        this.state = {
            redirect: false,
            firstName: '',
            lastName: '',
            email: '',
            userName: '',
            userId: '',
            profilePic: '',
            fileObject: '',
            fileName: '',
            fileType: '',
            fileSize: '',
            filePayload: '',
            errorMsg: false,
            errorMsg2: false,
            errorMsg3: false,
        }
    }

    handleClose(){
        this.setState({
            show:false,
            // clear file state when modal closes
            fileType: '',
            fileSize: '',
            fileObject: '',
            filePayload: ''
        });
    }

    handleShow(){
        this.setState({show:true});
    }

    onChange(e){
        var file = e.target.files[0];

        var dataTypeURL = new FileReader();
        var arrayBuffer = new FileReader();

        this.setState({
            fileObject: e.target.files[0],
            fileName: file.name,
            fileSize: file.size,
        });

        // Scan the file type for it's "magic numbers". to determine the real file type in case user spoofs the file type of the file he is changing.
        arrayBuffer.onload = (e) => {
            let arr = (new Uint8Array(e.target.result)).subarray(0, 4);
            let header = "";
            let i;
            for(i = 0; i < arr.length; i++){
                header += arr[i].toString(16);
            }
            let truefileType;
            switch (header) {
                case "89504e47":
                    truefileType = "image/png";
                    break;
                case "47494638":
                    truefileType = "image/gif";
                    break;
                case "ffd8ffe0":
                case "ffd8ffe1":
                case "ffd8ffe2":
                case "ffd8ffe3":
                case "ffd8ffe8":
                    truefileType = "image/jpeg";
                    break;
                default:
                    truefileType = "unknown";
                    break;
            }
            this.setState({
                fileType: truefileType
            });
        }

        dataTypeURL.onload = (e) => {
            this.setState({
                filePayload: e.target.result,
                profilePic: e.target.result
            });
        };
        dataTypeURL.readAsDataURL(file);
        arrayBuffer.readAsArrayBuffer(file);
    }

    async onSubmit(e){
        e.preventDefault();

        // file size bytes in mb
        var fileCheck = Math.floor(Math.log(this.state.fileSize) / Math.log(1024));
        var allowedFileTypes = ['image/jpeg', 'image/jpg', 'image/png'];

        //Check if a uploaded photo was taken.
        if(this.state.fileObject === ''){
            this.setState({
                errorMsg: true,
                errorMsg2: false,
                errorMsg3: false,
            })
        } else if(!allowedFileTypes.includes(this.state.fileType)){
            // check file type
            this.setState({
                errorMsg: false,
                errorMsg2: true,
                errorMsg3: false,
            })
        } else if(fileCheck >= 2){
            // check file size
            this.setState({
                errorMsg: false,
                errorMsg2: false,
                errorMsg3: true,
            })
        }
        else {
            // Change users photo
            this.setState({
                errorMsg: false,
                errorMsg2: false,
                errorMsg3: false,
            })
            //console.log('passed all file checks');
            const updateData = {
                userName: this.state.userName,
                fileType: this.state.fileType,
                fileName: this.state.fileName,
                fileSize: this.state.fileSize,
                filePayload: this.state.filePayload,
            }
            const updateprofileData = await profileService.updatePhoto(updateData)

            //console.log(updateprofileData);

            location.href='/Profilepage';

        }
    }

    async selectData(){
        if(this.state.profilePic === ''){
            await this.setState({isLoading:true})
        }

        const selectData = {
            profilePic: this.state.profilePic,
            userName: this.state.userName
        }
        const selectprofileData = await profileService.selectPhoto(selectData)

        await this.setState({
            profilePic: 'https://awss3link/blah-blah-blah/' + selectprofileData[0].profilePic
        })
    }

    async componentDidMount(){
        await this.userStatus();
        await this.selectData();

        console.log("Url Params", this.props.match.params);
    }

    render(){
        return (
            <div className="container">
                <Header />
                <div className="row">
                    <div className="col-md-5" id="profile-left">
                    {this.props.match.params.userid == this.state.userId ? <h1>Welcome, {this.state.userName}</h1> : <h1>{this.props.match.params.username}</h1> }
                        <div className="img-rounded">
                            <img src={this.state.profilePic} alt="profile picture" />
                        </div>

                        {this.props.match.params.userid == this.state.userId ? <Button onClick={this.handleShow}>Upload New Photo</Button> : null }

                        <Modal show={this.state.show} onHide={this.handleClose}>
                            <form
                                method="POST"
                                onSubmit={e => this.onSubmit(e)}
                            >
                            <Modal.Header closeButton>
                                <Modal.Title>Upload New Photo</Modal.Title>
                            </Modal.Header>
                            <Modal.Body>
                                {/* Please upload a photo. */}
                                {this.state.errorMsg === true ? <span style={{color: 'red'}}>Please upload a photo</span> : null}
                                {/* Wrong file type. */}
                                {this.state.errorMsg2 === true ? <span style={{color: 'red'}}>Please upload only JPG or PNG</span> : null}
                                {/* File is too big. */}
                                {this.state.errorMsg3 === true ? <span style={{color: 'red'}}>Please upload a file less than 3MB.</span> : null}
                                <input
                                    type="file"
                                    className="form-control-file"
                                    name="profilePic"
                                    onChange={e => this.onChange(e)}
                                />
                            </Modal.Body>
                            </form>
                        </Modal>
                    </div>
                </div>
            </div>
        )
    }
}

export default Profilepage;

0 个答案:

没有答案