【问题标题】:items array is empty when trying to add items to cart尝试将商品添加到购物车时,项目数组为空
【发布时间】:2020-03-23 10:50:57
【问题描述】:

serverso 我正在尝试将商品添加到购物车但数组为空,我找不到问题所在。我认为 node.js 的后端工作正常,因为当我通过在浏览器中输入 url http://localhost:4000/cart/5dd7668f33c21d811b74f403 将商品添加到购物车时,它会增加购物车数量并重定向到 http://localhost:4000/cart/ 但是当我导航到 http://localhost:3000/cart/当我使用 chrome 开发人员工具检查它时,浏览器中没有显示任何内容,并且 items 数组为空。我认为前端反应和后端没有正确链接。我添加了它的图片以进一步澄清,这是我的应用程序的代码。 服务器.js

const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const cors = require("cors");
const cookieParser = require("cookie-parser");
const mongoose = require("mongoose");
let Book = require("./models/bookModel");
var session = require("express-session");
var MongoStore = require("connect-mongo")(session);
var flash = require("connect-flash");

const port = 4000;

app.use(cors());
app.use(bodyParser.json());

app.use(cookieParser());

app.use(
  session({
    secret: "keyboard cat",
    resave: false,
    saveUninitialized: true,
    store: new MongoStore({ mongooseConnection: mongoose.connection }),
    cookie: { maxAge: 180 * 60 * 1000 }
  })
);


app.use(flash());

mongoose.connect("mongodb://127.0.0.1:27017/books", { useNewUrlParser: true });
const connection = mongoose.connection;

connection.once("open", function() {
  console.log("MongoDB database connection established successfully..");
});

const bookRoutes = express.Router();
app.use("/books", bookRoutes);
const cartRoutes = express.Router();
app.use("/cart", cartRoutes);

bookRoutes.route("/").get(function(req, res) {
  Book.find(function(err, books) {
    if (err) {
      console.log(err);
    } else {
      res.json(books);
    }
  });
});

bookRoutes.route("/:id").get(function(req, res) {
  let id = req.params.id;
  Book.findById(id, function(err, book) {
    res.json(book);
  });
});

cartRoutes.route("/").get(function(req, res) {
  var cart = req.session.cart;
  var displayCart = { items: [], total: 0 };
  var total = 0;

  for (var item in cart) {
    displayCart.items.push(cart[item]);
    total += cart[item].qty * cart[item].price;
  }
  displayCart.total = total;

  return res.json(displayCart);
});

cartRoutes.route("/:id").get(function(req, res) {
  req.session.cart = req.session.cart || {};
  var cart = req.session.cart;
  let id = req.params.id;
  Book.findById(id, function(err, book) {
    if (err) {
      console.log(err);
    }
    if (cart[id]) {
      cart[id].qty++;
    } else {
      cart[id] = {
        item: book._id,
        title: book.title,
        price: book.price,
        qty: 1
      };
    }
    console.log(req.session.cart);
    res.redirect("/cart");
  });
});
app.listen(port, function() {
  console.log("Server is running on Port: " + port);
});

App.js

import React, { Component } from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import BooksList from "./components/book-list.component.js";
import BookDetails from "./components/book-details.component.js";
import "bootstrap/dist/css/bootstrap.min.css";
import Navigation from "./components/navigation.component";
import Cart from "./components/cart1.component";

class App extends Component {
  render() {
    return (
      <Router>
        <Navigation></Navigation>

        <Route
          path="/"
          exact
          render={() => (
            <div className="container">
              <BooksList></BooksList>
            </div>
          )}
        ></Route>
        <Route path="/books/:id" exact component={BookDetails}></Route>
        <Route path="/cart" exact component={Cart}></Route>
      </Router>
    );
  }
}

export default App;

book-details.componentjs

import React, { Component } from "react";
import "../css/styles.css";
import axios from "axios";

export default class BookDetails extends Component {
  constructor(props) {
    super(props);
    this.state = {
      book: [],
      items: []
    };
  }

  componentDidMount() {
    axios
      .get("http://localhost:4000/books/" + this.props.match.params.id)
      .then(response => {
        this.setState({ book: response.data });
      })
      .catch(function(err) {
        console.log(err);
      });
  }

  AddToCart = e => {
    let id = e.currentTarget.getAttribute("id");
    axios.get(`http://localhost:4000/cart/${id}`).then(() => {
      window.location.href = "http://localhost:3000/cart";
    });
  };

  render() {
    const { book, quantity } = this.state;
    return (
      <div className="container">
        <div className="row">
          <div className="col sm-4">
            <img src={`./images/${book.cover}`}></img>
          </div>
          <div className="col sm-8">
            <h2>{book.title}</h2>
            <ul>
              <li>Category: {book.category}</li>
              <li>Author: {book.author}</li>
            </ul>
            <p className="button blue">${book.price}</p>
            <p>{book.description}</p>
            <button id={book._id} onClick={this.AddToCart}>
              Add to Cart
            </button>
          </div>
        </div>
      </div>
    );
  }
}

cart1.component.js

import React, { Component } from "react";
import axios from "axios";
import CartItem from "./cart1-item.component.js";
import "bootstrap/dist/css/bootstrap.min.css";
import { throws } from "assert";

export default class Cart extends Component {
  constructor(props) {
    super(props);
    this.state = {
      items: []
    };
  }
  componentDidMount() {
    axios
      .get("http://localhost:4000/cart/")
      .then(response => {
        this.setState({
          items: response.data.items
        });
      })
      .catch(function(err) {
        console.log(err);
      });
  }

  checkItems() {
    return this.state.items.map((currItem, i) => {
      return <CartItem book={currItem} key={i}></CartItem>;
    });
  }

  Calculate = item => {
    return item.qty * item.price;
  };

  render() {
    return (
      <div className="container">
        <div className="row">{this.checkItems()}</div>
      </div>
    );
  }
}

cart-tem1.component.js

import React, { Component } from "react";
import "bootstrap/dist/css/bootstrap.min.css";

const CartItem = props => {
  return (
    <div className="container">
      <h2>{props.book.title}</h2>
    </div>
  );
};

export default CartItem;

我已经坚持了将近一个星期,并尽我所能使其工作,但无济于事,任何帮助将不胜感激

[chromedevelopertools][2]

【问题讨论】:

    标签: node.js reactjs express


    【解决方案1】:

    如果不尝试就很难调试所有内容,但我很确定您的会话有问题。

    会话由 cookie(浏览器在每次请求时发送的内容)实现,出于安全原因,它们依赖于域。它们不能很好地与单页应用程序配合使用。

    当您转到端口:4000 时,浏览器会为您发送 cookie,但在端口:3000 上,axios 应该从其他域发送 cookie。尝试在您的通话中添加此配置:

    axios.get('xxx', {withCredentials: true});

    它~可能有效,但我觉得你需要在其他地方做一些额外的工作才能首先初始化那个 cookie。

    如果您要使用 SPA(这是当今流行的选择),我建议您不要使用会话并尝试使您的服务器“无状态”。它还会有其他好处。你需要实现像 Oauth 或 JWT 之类的东西,而不是那个 cookie(如果你刚开始的话,我推荐 Jwt)。那有足够的关键字供您搜索! :)

    【讨论】:

    • 嘿,你能指导我完成 jwt 的事情吗?我对表达和反应比较陌生。这真的很有帮助。
    • 过程不短,找一些好的教程(我不知道你的背景所以推荐你一个)。可能是这样的? medium.com/swlh/… 那是后端,然后你需要发送你在前端的每个请求中生成的令牌
    猜你喜欢
    • 1970-01-01
    • 2016-12-19
    • 2020-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    相关资源
    最近更新 更多