当前位置: 首页 > 知识库问答 >
问题:

节点/反应客户端代理不工作,componentDidMount()未获取数据

徐隐水
2023-03-14

编辑:可在此处找到项目回购的链接。

当我的个人资料页面加载到React应用程序时,我正在尝试获取数据。我的客户端运行在localhost:3000上,服务器运行在localhost:5000上。

我还有一个代理在我的客户端文件夹的package.json指向localhost:5000(假设)。在我的服务器文件中,我也有cors,以及我过去使用过的所有常用的铃铛和哨子。

每当我的组件挂载时,在我的控制台中,我会收到一个404错误,说我的get请求失败,它说它试图访问localhost:3000/recipes-根据我的代理,这是错误的,因为它应该向localhost:5000发出请求。

然而,它变得更加棘手,因为为了测试它,我更改并硬编码了我的路由localhost:5000但即使这样也会返回404错误。

起初,我认为这是我的后端GET请求逻辑出了问题,但问题是,当我将使get请求在组件中的相同功能插入didUpdate()时,它成功地获取了所有的食谱(这是一个食谱应用程序),只是它触发了一个无限循环,变得疯狂,显然我不能这样。

有人知道这是怎么回事吗?为什么我的getRecipes()函数(发出get请求)在componentDidMount()内部不工作,出现404错误,无法成功代理,但在componentDidUpdate()内部工作?为什么是无限循环?

这是我的前端代码:

import React, { Component } from "react";
import {
  Button,
  Modal,
  ModalHeader,
  ModalBody,
  Form,
  FormGroup,
  Label,
  Input
} from "reactstrap";
import styles from "./RecipeList.module.css";
// import { addRecipe } from "../RecipeFunctions/RecipeFunctions";
import axios from "axios";
import RecipeItem from "../RecipeItem/RecipeItem";
import jwt_decode from "jwt-decode";

export default class RecipeList extends Component {
  state = {
    recipes: [],
    modal: false,
    email: "",
    recipeName: "",
    ingredients: "",
    directions: "",
    errors: {
      msg: ""
    }
  };

  toggle = () => {
    this.setState({
      modal: !this.state.modal
    });
  };

  onChange = e => {
    this.setState({
      [e.target.name]: e.target.value
    });
  };

  onSubmit = e => {
    e.preventDefault();

    const newRecipe = {
      user_email: this.state.email,
      title: this.state.recipeName,
      ingredients: this.state.ingredients,
      directions: this.state.directions
    };

    // Make Post Request w/ Axios from RecipeFunctions.js
    this.addRecipe(newRecipe);
    this.getRecipes();
  };

  getRecipes = () => {
    axios.get(`/recipes/${this.state.email}`).then(res => {
      this.setState({
        recipes: res.data
      });
    });
  };

  addRecipe = newRecipe => {
    axios.post("/recipes", newRecipe).then(response => {
      console.log("Recipe added.");
      console.log(this.state.email)
    });
  };

  deleteRecipe = id => {
    axios
      .delete(`/recipes/${id}`)
      .then(this.getRecipes())
      .catch(err => console.log(err));
  };

  viewRecipe = id => {
    axios
      .post(`/viewrecipe/${id}`)
      .then(this.getRecipes())
      .catch(err => console.log(err));
  };

  closeRecipe = id => {
    axios
      .post(`/closerecipe/${id}`)
      .then(this.getRecipes())
      .catch(err => console.log(err));
  };

  componentDidMount() {
    try {
      const token = localStorage.usertoken;
      const decoded = jwt_decode(token);
      this.setState({
        firstname: decoded.firstname,
        lastname: decoded.lastname,
        email: decoded.email
      });
    } catch {
      this.setState({
        errors: {
          msg: "You must be logged in to see your profile."
        }
      });
    }
    this.getRecipes();
  }

  render() {
    if (this.state.email) {
      return (
        <div id={styles.compWrapper} className="container">
          <div>
            <div id={styles.titleWrapper} className="col-sm-8 mx-auto">
              <h1 className="text-center">{this.state.firstname}'s Cookbook</h1>
            </div>
            <div className="text-center">
              <div>
                <Button
                  id={styles.addRecipeBtn}
                  outline
                  color="secondary"
                  onClick={this.toggle}
                  size="sm"
                >
                  Add Recipe
                </Button>
                <div className={styles.feedWrapper}>
                  <Modal
                    className={styles.addRecipeModal}
                    isOpen={this.state.modal}
                    toggle={this.toggle}
                  >
                    <ModalHeader toggle={this.toggle}>New Recipe</ModalHeader>
                    <ModalBody>
                      <Form onSubmit={this.onSubmit}>
                        <FormGroup>
                          <Label for="item">Recipe Name</Label>
                          <Input
                            type="text"
                            name="recipeName" // *must match this.state above
                            id="item"
                            placeholder="ex. Chicken Pot Pie"
                            onChange={this.onChange}
                          />
                          <Label className={styles.inputLabel} for="item">
                            Ingredients
                          </Label>
                          <Input
                            type="textarea"
                            size="lg"
                            name="ingredients" // *must match this.state above
                            id={styles.ingredientsTextArea}
                            onChange={this.onChange}
                          />
                          <Label className={styles.inputLabel} for="item">
                            Directions
                          </Label>
                          <Input
                            type="textarea"
                            size="lg"
                            name="directions" // *must match this.state above
                            id={styles.directionsTextArea}
                            onChange={this.onChange}
                          />
                          <Button
                            color="dark"
                            style={{ marginTop: "2rem" }}
                            block
                            onClick={this.toggle}
                          >
                            Add
                          </Button>
                        </FormGroup>
                      </Form>
                    </ModalBody>
                  </Modal>
                </div>
                <div
                  id={styles.recipeListWrapper}
                  className="recipe-list-container"
                >
                  {this.state.recipes.map(recipe => (
                    <RecipeItem
                      id={recipe._id}
                      title={recipe.title}
                      ingredients={recipe.ingredients}
                      directions={recipe.directions}
                      beingViewed={recipe.beingViewed}
                      viewRecipe={this.viewRecipe}
                      closeRecipe={this.closeRecipe}
                      deleteRecipe={this.deleteRecipe}
                    />
                  ))}
                </div>
              </div>
            </div>
          </div>
        </div>
      );
    } else {
      return (
        <p className="text-center jumbotron mt-5">{this.state.errors.msg}</p>
      );
    }
  }
}

这是我的server.js:

const express = require("express");
const path = require('path');
const cors = require("cors");
const bodyParser = require("body-parser");
const app = express();
const mongoose = require("mongoose");
const dotenv = require("dotenv");
const port = process.env.PORT || 5000;

app.use(bodyParser.json());
app.use(cors());
app.use(
  bodyParser.urlencoded({
    extended: false
  })
);

dotenv.config();
const db = process.env.DB_CONNECT;

const Users = require("./routes/Users");
const Recipes = require("./routes/Recipes");

app.use("/users", Users);
app.use("/recipes", Recipes);

mongoose
  .connect(db, {
    useUnifiedTopology: true,
    useNewUrlParser: true,
    useCreateIndex: true
  })
  .then(() => console.log("MongoDB Connected..."))
  .catch(() => console.log(err));

app.post("/viewrecipe/:id", (req, res) => {
  Recipe.findOneAndUpdate({ _id: req.params.id }, { $set: { beingViewed: true } })
    .then(res.send("Recipe being viewed."))
    .catch(err => console.log(err));
});

app.post("/closerecipe/:id", (req, res) => {
  Recipe.findOneAndUpdate({ _id: req.params.id }, { $set: { beingViewed: false } })
    .then(res.send("Recipe closed."))
    .catch(err => console.log(err));
});

app.get("/showrecipes", (req, res) => {
  Recipe.find({}).then(recipes => res.send(recipes));
});

app.delete("/deleterecipes", (req, res) => {
  Recipe.deleteMany({}).then(res.send("All recipes deleted. Database empty."));
});

// Serve static assets if in production
if(process.env.NODE_ENV === 'production') {
  // Set static folder
  app.use(express.static('client/build'));

  app.get('*', (req, res) => {
      res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
  });
}

app.listen(port, () => {
  console.log(`Server listening on port ${port}`);
});

如果需要,这里是实际的路线(食谱。是基于 /recipes的快速路由器):

recipes.get("/:useremail", (req, res) => {
  if (!req.params.useremail) {
    res.send("You must be logged in to access recipes.");
  }
  Recipe.find({
    user_email: req.params.useremail
  })
    .then(recipes => {
        res.send(recipes)
    .catch(err => {
      res.send("error: " + err);
    });
});

任何帮助都很感激!

共有1个答案

羊舌胡非
2023-03-14

在获取请求中,尝试使用192.168.17.161:5000而不是localhost:5000

 类似资料:
  • 问题内容: 因此,我正在使用node / express + jade组合编写应用程序。 我有,已在客户端上加载。在该文件中,我有调用其他JavaScript文件中的函数的代码。我的尝试是使用 为了加载内容(就像我在服务器端一样),然后再加载该文件的调用函数。但是,未在客户端定义,并且抛出形式的错误。 这些其他JS文件也在客户端的运行时加载,因为我将链接放置在网页的标题处。因此,客户端知道从这些其

  • 我试图使用Apache创建一个反向代理。我正在使用Apache为一个php应用程序提供服务,并在node中编写了一个使用Express的API。 在我的PHP应用程序中,我使用AJAX调用node来检索JSON。我希望使用端口80进行PHP应用程序中的调用,并使用Apache来表达一个反向代理。

  • 我有一个wsdl: 我想提交信息以获得回应。我创建了client.php如下: 但它在浏览器中显示错误: SoapFault对象([消息:受保护]= 我错在哪里?对此,可能的解决方案是什么? 编辑: 我已经创建了一个php文件:client。php 但它产生了这个错误: 调用错误:响应不是文本/xml类型:应用程序/wsdl xmlHTTP/1.1 200确定日期:星期二,9月17日2013 15

  • 问题内容: 我建立了一个新的react项目,由于某种原因,该方法没有被调用。 我已经通过调用in 验证了此行为,但是在控制台中看不到它的输出。 此外,无法正常工作。 关于为什么不调用,我感到很困惑。我尝试同时使用React“ v0.14.0”和“ v0.14.3”。 为什么不调用“ componentDidMount”? 码: 问题答案: 所以…瞧瞧......我终于开始工作了(在后端专家的帮助下

  • 问题内容: 因此,我正在使用node / express + jade组合编写应用程序。 我有,已在客户端上加载。在该文件中,我有调用其他JavaScript文件中的函数的代码。我的尝试是使用 为了加载内容(就像我在服务器端一样),然后再加载该文件的调用函数。但是,未在客户端定义,并且抛出形式的错误。 这些其他JS文件也在客户端的运行时加载,因为我将链接放置在网页的标题处。因此,客户端知道从这些其

  • 我的编程任务要求我在客户端和服务器之间创建一个代理。我的客户端通过代理向服务器发出请求,然后代理将其转发并将服务器的响应返回给客户端。 以下是我采取的步骤: 1) 从客户端获取请求并将请求数据存储到字节数组中 2) 使用缓冲读取器读取字节数组 3) 从host:header字段获取主机名,并使用它创建一个serverSocket 4) 将请求数据转发到serverSocket outputstre