You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

电商网站产品图片上传报错:Cannot read properties of undefined (reading 'post')

电商网站产品图片上传报错:Cannot read properties of undefined (reading 'post')

搭建电商网站时,尝试上传本地图片修改产品图片失败,报错信息:Cannot read properties of undefined (reading 'post')

错误截图:
错误截图

相关代码文件

uploadRouter.js

import multer from "multer";
import express from "express";
import { isAuth } from "../util";

const uploadRouter = express.Router();
const storage = multer.diskStorage({
  destination(req, file, cb) {
    cb(null, "uploads/");
  }, filename(req, file, cb) {
    cb(null, `${Date.now()}.jpg`);
  },
});

const upload = multer({ storage });

uploadRouter.post("/", isAuth, upload.single("image"), (req, res) => {
  res.send(`/${req.file.path}`);
});

export default uploadRouter;

server.js

import express from "express";
import dotenv from "dotenv";
import mongoose from "mongoose";
import path from "path";
import userRoute from "./routes/userRoute";
import productRoute from "./routes/productRoute";
import orderRouter from "./routes/orderRouter";
import uploadRouter from "./routes/uploadRouter";


dotenv.config();
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

mongoose.connect(process.env.MONGODB_URL || "mongodb://localhost/amason", {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  useCreateIndex: true,
});

app.use("/api/uploads", uploadRouter);
app.use("/api/users", userRoute);
app.use("/api/products", productRoute);
app.use("/api/orders", orderRouter);


const __dirname = path.resolve();
app.use("/uploads", express.static(path.join(__dirname, "/uploads")));

app.get("/", (req, res) => {
  res.send("Server is ready");
});

app.use((err, req, res, next) => {
  res.status(500).send({ message: err.message });
});

const port = process.env.PORT || 5000;
app.listen(port, () => {
  console.log(`Serve at http://localhost:${port}`);
});

productEditPage.jsx

import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { detailsProduct, updateProduct } from "../actions/productActions";
import LoadingBox from "../components/loadingBox";
import MessageBox from "../components/messageBox";
import { PRODUCT_UPDATE_RESET } from "../reducers/actionTypes";
import { axios } from "axios";
import NavBar from "../components/navbar";
import Footer from "../components/footer";


function ProductEditPage(props) {
  const productId = props.match.params.id;
  const [name, setName] = useState("");
  const [price, setPrice] = useState("");
  const [category, setCategory] = useState("");
  const [image, setImage] = useState("");
  const [brand, setBrand] = useState("");
  const [countInStock, setCountInStock] = useState("");
  const [description, setDescription] = useState("");

  const productDetails = useSelector((state) => state.productDetails);
  const { loading, error, product } = productDetails;

  const productUpdate = useSelector((state) => state.productUpdate);
  const {
    loading: loadingUpdate,
    error: errorUpdate,
    success: successUpdate,
  } = productUpdate;

  const dispatch = useDispatch();

  useEffect(() => {
    if (successUpdate) {
      props.history.push("/productlist");
    }
    if (!product || product._id !== productId || successUpdate) {
      dispatch({ type: PRODUCT_UPDATE_RESET });
      dispatch(detailsProduct(productId));
    } else {
      setName(product.name);
      setPrice(product.price);
      setImage(product.image);
      setCategory(product.category);
      setCountInStock(product.countInStock);
      setBrand(product.brand);
      setDescription(product.description);
    }
  }, [product, dispatch, productId, successUpdate, props.history]);

  const submitHandler = (e) => {
    e.preventDefault();
    dispatch(
      updateProduct({
        _id: productId,
        name,
        price,
        image,
        brand,
        category,
        countInStock,
        description,
      })
    );
  };


  const [loadingUpload, setLoadingUpload] = useState(false);
  const [errorUpload, setErrorUpload] = useState("");

  const userSignin = useSelector((state) => state.userSignin);
  const { userInfo } = userSignin;

  const uploadFileHandler = async (e) => {
    const file = e.target.files[0];

    const bodyFormData = new FormData();

    bodyFormData.append("image", file);
    setLoadingUpload(true);
    try {
      const { data } = await axios.post("/api/uploads", bodyFormData, {
        headers: {
          "Content-Type": "multipart/form-data",
          Authorization: `Bearer ${userInfo.token}`,
        },
      });

      setImage(data);
      setLoadingUpload(false);
    } catch (error) {
      setErrorUpload(error.message);
      setLoadingUpload(false);
      console.log(error);
    }
  };


  return (
    <div className="container  ">
      <div className="row content ">
        <div className="row justify-content-between content_header mt-4">
          <div className="col-4">
            <p>Edit Product {productId}</p>
          </div>
        </div>
        {loadingUpdate && <LoadingBox></LoadingBox>}
        {errorUpdate && (
          <MessageBox variant="danger">{errorUpdate}</MessageBox>
        )}
        {loading ? (
          <LoadingBox></LoadingBox>
        ) : error ? (
          <MessageBox variant="danger">{error}</MessageBox>
        ) : (
          <>
            <div className="row ">
              <form
                className=" edit mt-5 mb-5 col col-lg-8 "
                onSubmit={submitHandler}
              >
                <div className="row g-3">
                  <div className="col mb-3">
                    <label htmlFor="name" className="form-label">
                      Name
                    </label>
                    <input
                      type="text"
                      className="form-control "
                      id="name"
                      value={name}
                      placeholder="Enter name"
                      onChange={(e) => setName(e.target.value)}
                    />
                  </div>

                  <div className="col mb-4">
                    <label htmlFor="price" className="form-label">
                      Price
                    </label>
                    <input
                      type="text"
                      className="form-control"
                      id="price"
                      value={price}
                      placeholder="Enter price"
                      onChange={(e) => setPrice(e.target.value)}
                    />
                  </div>
                </div>

                <div className="row g-3">
                  <div className="col mb-4">
                    <label htmlFor="brand" className="form-label">
                      Brand
                    </label>
                    <input
                      type="text"
                      className="form-control"
                      id="brand"
                      value={brand}
                      placeholder="Enter brand"
                      onChange={(e) => setBrand(e.target.value)}
                    />
                  </div>
                </div>

                <div className="col mb-4">
                  <label htmlFor="image" className="form-label">
                    Image
                  </label>
                  <input
                    type="text"
                    className="form-control"
                    id="image"
                    value={image}
                    placeholder="Enter image"
                    onChange={(e) => setImage(e.target.value)}
                  />
                </div>

                <div className="mb-4">
                  <label htmlFor="imageFile" className="form-label">
                    Image File
                  </label>
                  <input
                    className="form-control"
                    type="file"
                    id="imageFile"
                    label="Choose Image"
                    onChange={uploadFileHandler}
                    multiple
                  />
                  {loadingUpload && <LoadingBox></LoadingBox>}
                  {errorUpload && (
                    <MessageBox variant="danger">{errorUpload}</MessageBox>
                  )}
                </div>

                <div className="row g-3">
                  <div className="col mb-4">
                    <label htmlFor="countInStock" className="form-label">
                      CountInStock
                    </label>
                    <input
                      type="text"
                      className="form-control"
                      id="countInStock"
                      value={countInStock}
                      placeholder="Enter countInStock"
                      onChange={(e) => setCountInStock(e.target.value)}
                    />
                  </div>
                  <div className="col mb-4">
                    <label htmlFor="category" className="form-label">
                      Category
                    </label>
                    <input
                      type="text"
                      className="form-control"
                      id="category"
                      value={category}
                      placeholder="Enter category"
                      onChange={(e) => setCategory(e.target.value)}
                    />
                  </div>
                </div>

                <div className="mb-4">
                  <label htmlFor="description" className="form-label">
                    Description
                  </label>
                  <textarea
                    className="form-control"
                    id="description"
                    value={description}
                    placeholder="Enter description"
                    onChange={(e) => setDescription(e.target.value)}
                  />
                </div>

                <div className="row g-3">
                  <div className="col mb-4 ">
                    <button type="submit" className="btn btn-secondary ">
                      Update
                    </button>
                  </div>
                </div>
              </form>
            </div>
          </>
        )}
      </div>
    </div>
  );
}

问题解决方法

报错核心原因是axios导入方式错误:
在productEditPage.jsx中,你使用了命名导入import { axios } from "axios";,但axios是默认导出,正确的导入方式应该是:

import axios from "axios";

修改后,axios对象会被正确加载,调用axios.post时就不会出现undefined报错。

额外检查点:

  1. 确认项目根目录下的uploads文件夹已创建,multer需要该目录存储上传文件
  2. 验证后端/api/uploads路由已正确挂载,且isAuth中间件能正常验证用户权限
  3. 确保上传的文件符合multer配置的类型(当前只处理jpg,可根据需求扩展)

内容的提问来源于stack exchange,提问作者Susan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 02:33:29