【问题标题】:Cant send photo from React frontend to express backend after build (create-react-app)构建后无法将照片从 React 前端发送到表达后端(create-react-app)
【发布时间】:2020-10-11 17:36:16
【问题描述】:

好的,我有一个 MERN 应用程序 (CRA) 和照片上传。一切都很好,但是当我执行 npm run build 时,我无法将照片(超过 1MB)发送到后端。我已经使用邮递员进行测试并再次工作得很好:)。在开发模式下它的工作。当我想上传照片时,有些东西阻止了来自前端的请求。我已经检查了 morgan 的日志,它表明这个带有大照片上传的请求没有发生。我使用 axios 与后端通信并快速上传文件,但后端运行良好。我不知道是什么挡住了我的照片。调试模式下的快速文件上传也告诉“请求不符合上传条件!”

redux 中的操作:

  export const addGalleryPhoto = (file) => async (dispatch) => {
  const config = {
    headers: {
      "Content-Type": "multipart/form-data",
    },
  };
  try {
    await axios.put(`/api/v1/config/uploadGalleryPhoto`, file, config);
    dispatch(getPhotos());
  } catch (err) {
    const errors = err.response.data.error.split(",");
    if (errors) {
      errors.forEach((error) => dispatch(setAlert(error, "error")));
    }
    dispatch({ LOAD_PHOTOS_FAILED });
  }
};

节点中的控制器:

exports.uploadGalleryPhoto = asyncHandler(async (req, res, next) => {
  if (!req.files) {
    return next(new ErrorResponse(`Dodaj plik`, 400));
  }

  const file = req.files.file;

  // Make sure the image is a photo
  if (!file.mimetype.startsWith("image")) {
    return next(new ErrorResponse(`Możesz wysłać tylko zdjęcia`, 400));
  }

  if (file.size > process.env.MAX_FILE_UPLOAD) {
    return next(
      new ErrorResponse(
        `Zbyt duże zdjęcie. Maksymalny rozmiar pliku: ${Math.round(
          process.env.MAX_FILE_UPLOAD / 1024
        )} MB`,
        400
      )
    );
  }

  file.name = `photo_${uuid()}${path.parse(file.name).ext}`;

  file.mv(`${process.env.FILE_UPLOAD_PATH}/${file.name}`, async (err) => {
    if (err) {
      console.error(err);
      return next(new ErrorResponse(`Problem with file upload`, 500));
    }
    const config = await Config.find();
    await Config.findByIdAndUpdate(config[0].id, {
      galleryPhotos: [...config[0].galleryPhotos, file.name],
    });

    res.status(200).json({
      success: true,
      data: file.name,
    });
  });
});

图库组件:

import React, { useEffect, useState, useRef, Fragment } from "react";
import PropTypes from "prop-types";
import { Card, Modal, Button } from "antd";
import { DeleteOutlined } from "@ant-design/icons";
import Spinner from "./../layout/Spinner";
import { connect } from "react-redux";
import {
  addGalleryPhoto,
  getPhotos,
  deletePhoto
} from "./../../store/actions/gallery";

const AdminGallery = ({ photos, addGalleryPhoto, getPhotos, deletePhoto }) => {
  useEffect(() => {
    getPhotos();
  }, [getPhotos]);
  const fileInput = useRef();
  const [value, setValue] = useState("");
  const [formData, setFormData] = useState({
    deleteVisible: false,
    photo: null
  });

  const onSubmit = e => {
    e.preventDefault();
    const formData = new FormData();
    formData.append("file", value);
    addGalleryPhoto(formData);
    setValue("");
  };

  if (photos.loading || photos.photos.null) {
    return <Spinner />;
  } else {
    return (
      <Fragment>
        <div className="admin-gallery">
          <div>
            <input
              type="file"
              style={{ display: "none" }}
              ref={fileInput}
              onChange={e => setValue(e.target.files[0])}
            />
            {value === "" ? (
              <button
                type="button"
                className="btn btn--primary"
                onClick={e => fileInput.current.click()}
              >
                Dodaj plik
              </button>
            ) : (
              <button
                type="button"
                className="btn btn--primary"
                onClick={e => onSubmit(e)}
              >
                Wyślij zdjęcie
              </button>
            )}

            <div>
              {photos.photos.length === 0 ? (
                <div className="no-content">Brak Zdjęć</div>
              ) : (
                <div className="admin-gallery__photo-wrapper">
                  {photos.photos.map(item => {
                    return (
                      <Card
                        style={{ padding: "0 !important" }}
                        key={item}
                        actions={[
                          <DeleteOutlined
                            onClick={() =>
                              setFormData({
                                ...formData,
                                deleteVisible: true,
                                photo: item
                              })
                            }
                          />
                        ]}
                      >
                        <img
                          className="admin-gallery__photo"
                          src={`${process.env.PUBLIC_URL}/uploads/${item}`}
                          alt="photo"
                        />
                      </Card>
                    );
                  })}
                </div>
              )}
            </div>
          </div>
        </div>
        {formData.deleteVisible && formData.photo !== null ? (
          <Modal
            visible={formData.deleteVisible}
            title="Kasowanie zdjęcia"
            onOk={() => {
              deletePhoto(formData.photo);
              setFormData({ ...formData, deleteVisible: false, photo: null });
            }}
            onCancel={() =>
              setFormData({ ...formData, deleteVisible: false, photo: null })
            }
            footer={[
              <Button
                key="back"
                onClick={() =>
                  setFormData({
                    ...formData,
                    deleteVisible: false,
                    photo: null
                  })
                }
              >
                Zamknij
              </Button>,
              <Button
                key="accept"
                onClick={() => {
                  deletePhoto(formData.photo);
                  setFormData({
                    ...formData,
                    deleteVisible: false,
                    photo: null
                  });
                }}
              >
                Skasuj
              </Button>
            ]}
          >
            <p>Na pewno chcesz skasować to zdjęcie?</p>
          </Modal>
        ) : (
          ""
        )}
      </Fragment>
    );
  }
};

AdminGallery.propTypes = {
  photos: PropTypes.object.isRequired,
  getPhotos: PropTypes.func.isRequired,
  addGalleryPhoto: PropTypes.func.isRequired,
  deletePhoto: PropTypes.func.isRequired
};

const mapStateToProps = state => ({
  photos: state.photos
});

export default connect(mapStateToProps, {
  addGalleryPhoto,
  getPhotos,
  deletePhoto
})(AdminGallery);

【问题讨论】:

  • 这是在本地开发盒上的生产版本中发生的,还是在另一个(生产?暂存?)环境中发生的?
  • 您能上传您的代码以便我们尝试调试吗?
  • 这发生在数字海洋水滴上,是的,我稍后会添加一段代码:)

标签: reactjs express create-react-app


【解决方案1】:

好的,伙计们,我发现了一个问题。我的 Droplet 上有 nginx,在 nginx 中上传的默认文件大小设置为 1mb。 nginx conf中的这一行将完成client_max_body_size 100M;的工作,当然以100M为例。

【讨论】:

    猜你喜欢
    • 2019-09-07
    • 2021-02-06
    • 1970-01-01
    • 1970-01-01
    • 2022-01-28
    • 2020-10-20
    • 2021-04-28
    • 2018-08-06
    • 2019-10-22
    相关资源
    最近更新 更多