React JS,未通过https上传到节点服务器的文件

时间:2020-10-18 22:54:57

标签: reactjs file https upload busboy

我上传的文件有问题。将网站部署到Firebase后,它可以在localhost上完美运行,但不能与https一起使用。

我在React中的上传表单如下:

const UploadInvoice = (props) => {
    const [selectedFiles, setSelectedFiles] = useState([]);

    function handleValidSubmit(event, values) {
        if (selectedFiles && selectedFiles.length > 0) {
            selectedFiles.map((file, index) => {
                try {
                    let reader = new FileReader();
                    reader.readAsDataURL(file);
                    reader.onload = async (e) => {
                        const fileNameResult = await fetch(e.target.result).then(res => res.blob());
                        fileNameResult.name = file.name;
                        let data = new FormData();
                        data.append('file', fileNameResult, file.name);
                        props.uploadOCRInvoice(data);
                    };
                } catch (error) {
                    console.log(error);
                }
            });
        } else {
            toastr.warning("Please add your invoice!");
        }
    }

    useEffect(() => {
    }, [props.success]);

    function handleAcceptedFiles(files) {
        files.map(file => Object.assign(file, {
            preview: URL.createObjectURL(file),
            formattedSize: formatBytes(file.size)
        }));

        setSelectedFiles(files);
    };

    function formatBytes(bytes, decimals = 2) {
        if (bytes === 0) return '0 Bytes';
        const k = 1024;
        const dm = decimals < 0 ? 0 : decimals;
        const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];

        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
    };

    function getUploadErrorMessage(error){
        console.log(error);
        if(error == "MOLLIE_NOT_CONNECTED"){
            return "Mollie is not connected, please connect your Mollie account!";
        }

        return "Something went wrong, please try again!";
    }

    return (
        <AvForm className="form-horizontal" onValidSubmit={(e, v) => {
            handleValidSubmit(e, v)
        }}>
            <div>
                <Row>
                    <Col>
                        {props.error && props.error.length > 0 ?
                            <Alert color="danger" role="alert">
                                {getUploadErrorMessage(props.error)}
                            </Alert>
                            : null}
                    </Col>
                </Row>
                <Row>
                    <Col>
                        <Dropzone
                            multiple={false}
                            required
                            accept={".pdf"}
                            onDrop={(acceptedFiles) => {
                                handleAcceptedFiles(acceptedFiles)
                            }}>
                            {({getRootProps, getInputProps}) => (
                                <div className="dropzone">
                                    <div
                                        className="dz-message needsclick"
                                        {...getRootProps()}
                                    >
                                        <input {...getInputProps()} />
                                        <div className="dz-message needsclick">
                                            <div className="mb-3">
                                                <i className="display-4 text-muted bx bxs-cloud-upload"></i>
                                            </div>
                                            <h4>Drop files here or click to upload.</h4>
                                        </div>
                                    </div>
                                </div>
                            )}
                        </Dropzone>
                    </Col>
                </Row>
                <Row>
                    <Col>
                        <div
                            className="dropzone-previews mt-3 mb-3"
                            id="file-previews">
                            {selectedFiles.map((f, i) => {
                                return (
                                    <Card
                                        className="mt-1 mb-0 shadow-none border
                                        key={i + "-file"}
                                    >
                                        <div className="p-2">
                                            <Row className="align-items-center">
                                                <Col>
                                                    <Link
                                                        to="#"
                                                        className="text-muted font-weight-bold"
                                                    >
                                                        {f.name}
                                                    </Link>
                                                    <p className="mb-0">
                                                        <strong>{f.formattedSize}</strong>
                                                    </p>
                                                </Col>
                                            </Row>
                                        </div>
                                    </Card>
                                );
                            })}
                        </div>
                    </Col>
                </Row>
            </div>
            {selectedFiles.length > 0 ? <Row><Col>
                <div className="text-right">
                    <button type="submit" className="btn btn-success save-event">Upload</button>
                </div>
            </Col></Row> : null}
        </AvForm>
    );
}

const mapStatetoProps = state => {
    const {error, success} = state.InvoiceUpload;
    return {error, success};
};

export default connect(mapStatetoProps, {uploadSuccess, uploadError, uploadInvoice})(UploadInvoice);

在我的节点js服务器上:

const uploadInvoice = async (req, res, next) => {
    try {
        req.pipe(req.busboy);

        let uploadData = null;
        req.busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
            const filepath = path.join(os.tmpdir(), filename);
            uploadData = {file: filepath, type: mimetype, fileName: filename, uuid: uuid()};
            file.pipe(fs.createWriteStream(filepath));
        });

        req.busboy.on('finish', async () => {
                res.status(201).send();
            }).catch((error) => {
                console.log(error);
                return next(new UploadWizardFailed(), req, res, next);
            });
        });
    } catch (error) {
        next(error);
    }
}

我使用了关注API发布请求

const postFileSecured = (url, data) => {
    let user = getAuthenticatedUser();
    return api.post(url, data, {
        headers: {
            'Authorization': user.idToken,
            "Content-Type": "multipart/form-data"
        }
    }).then(response => {
        if (response.status === 400 || response.status === 500 || response.status === 404) {
            console.log('Error received =>');
            console.log(response);
            throw response;
        }
        return response.data;
    }).catch(err => {
        throw err.response;
    });
};

但是当我在生产环境中上传文件时,uploadData始终为空。有人知道如何解决此问题吗?

0 个答案:

没有答案