reactjs 使用axios / fetch从节点获取数据以进行React

wnrlj8wa  于 2023-01-12  发布在  React
关注(0)|答案(1)|浏览(133)

晚上好,伙计们,请我需要一个如何从节点获取数据的帮助作出React,我被困在这里2个星期了。
这是我的后端代码;
服务器. js:

require("dotenv").config();

const app = require("./src/app");

const port = process.env.PORT || 4000;

app.get("/", (req, res) => {
  res.send("Hello World!");
});

app.listen(port, () => {
  console.log(`Server is running on port http://localhost:${port}`);
});

应用程序js:

const express = require("express");
const cors = require("cors");
const cookieSession = require("cookie-session");

const app = express();
app.use(
  cors({
    origin: ["http://localhost:4000/api", "http://localhost:3000"],
  })
);
app.use(function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept"
  );
  next();
});

app.use(express.json());
app.use(express({ type: "application/vnd.api+json" }));
app.use(express.urlencoded({ extended: true }));
app.use(
  cookieSession({
    name: process.env.COOKIE_NAME, //ookie name in .env
    secret: process.env.COOKIE_SECRET, //secret name in .env
    httpOnly: true,
    sameSite: "strict",
    maxAge: 24 * 60 * 60 * 1000, // 24 hours duration before expire
  })
);

app.use("/uploads", express.static("uploads"));

const jobRoute = require("./routes/job.routes");
app.use("/api/", jobRoute);

module.exports = app;

service.js

const db = require("../config/database");
const notificationServices = require("./notification.services");
const { jobReuseQuery } = require("../job reuseable query/job.queries");

const createJob = async (body) => {
  const {
    title,
    salary_type,
    salary,
    job_types,
    description,
    company_id,
    sector_id,
    category_id,
  } = body;

  const { rows } = await db.query(
    `INSERT INTO jobs (title, salary_type, salary, job_types, description, company_id, sector_id, category_id) 
VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *`,
    [
      title,
      salary_type,
      salary,
      job_types,
      description,
      company_id,
      sector_id,
      category_id,
    ]
  );
  notificationServices.sendMatchJobsToUserProfiles(rows[0]);

  return rows[0];
};

const getAllJobs = async () => {
  const { rows } = await db.query("SELECT * FROM jobs");

  return rows;
};

controller.js

const jobService = require("../services/job.services");

const createJob = async (req, res) => {
  try {
    const job = await jobService.createJob(req.body);
    res.status(201).send({
      message: "Job created successfully",
      data: job,
    });
  } catch (err) {
    res.status(400).send(err.message);
  }
};

const getAllJobs = async (req, res) => {
  try {
    const jobs = await jobService.getAllJobs();
    res.status(200).send({ data: jobs });
  } catch (err) {
    res.status(400).send({ message: err.message });
  }
};

routes.js

const router = require("express-promise-router")();
const jobController = require("../controllers/job.controller");
const auth = require("../middleware/auth.middleware");

router.post("/jobs", auth, jobController.createJob);

auth.js

const db = require("../config/database");
const jwt = require("jsonwebtoken");
const dotenv = require("dotenv");
dotenv.config();

const auth = async (req, res, next) => {
  const token = req.session.token;

  if (!token) {
    return res.status(401).send({ error: "Please Authenticate" });
  }

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);

    const { rows } = await db.query("SELECT * FROM users WHERE id = $1", [
      decoded.id,
    ]);

    if (!rows[0]) {
      throw new Error("User not found");
    }
    req.user = rows[0];
    
    next();
  } catch (error) {
    return res.status(401).send({ error: error.message });
  }
};

module.exports = auth;

React前端代码;

import React, { useEffect } from "react";
import tech from "../../image/tech-big.svg";
import health from "../../image/health-big.svg";
import eng from "../../image/eng-big.svg";
import axios from "axios";
import { useState } from "react";

const Joblist = () => {
  const [name, setName] = useState([]);

  //first method
  const response = axios
    .get("http://localhost:4000/api/jobs/")
    .then((res) => res.json());
  console.log(response);

  //second method
  const fetchData = async () => {
    const newData = await fetch("http:localhost:4000/api/jobs", {
      method: "GET",
      headers: {
        "Content-Type": "application/json",
        ACCEPT: "application/json",
        "Access-Control-Allow-Credentials": true,
        "Access-Control-Allow-Origin": true,
        credentials: "same-origin",
        Authorization: `Bearer ${token}`,
      },
    }).then((res) => res.json());
    console.log(newData);
    setName(newData.jobs.name);

    fetchData();
  };

你可以在我的react中看到,我使用了2个方法来尝试从节点获取数据到react
我的浏览器控制台中的第一个方法返回错误:

Promise {<pending>}
GET http://localhost:4000/api/jobs/ 401 (Unauthorized)
Uncaught (in promise) AxiosError {message: 'Request failed with status code 401', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}

而第二个方法在浏览器控制台中不返回任何内容
我正在尝试从我的节点后端获取数据到前端react,但我的第一个方法记录错误,而第二个方法不记录任何内容

ni65a41a

ni65a41a1#

我认为您需要清理一下您的设置,因为您使用的是CORS,您可以先进行一些更改:

// .....
const app = express();

// with CORS you can do all your setting at the same place, so you don't need to set the header
const corsOptions = {
    origin: ["http://localhost:4000/api", "http://localhost:3000"],
    methods: "GET, POST, PUT, DELETE, OPTIONS, HEAD",
    credentials: true,  // for jwt/cookie !         
};
app.use(cors(corsOptions));

app.use(express.json());
app.use(express({ type: "application/vnd.api+json" }));
app.use(express.urlencoded({ extended: true }));
app.use(
  cookieSession({
        name: process.env.COOKIE_NAME,
        secret: process.env.COOKIE_SECRET, 
        maxAge: 24 * 60 * 60 * 1000,
        httpOnly: true,
        sameSite: false, //set this to "None" if you deploy to production on cross domaine.
        secure: false,  //set to true is required on production with https
   });

app.use("/uploads", express.static("uploads"));

const jobRoute = require("./routes/job.routes");
app.use("/api/", jobRoute);

module.exports = app;

更新获取部分我进行了清理(我删除了头),我注意到在job.controller.js上,您将data属性放在了响应json上。因此,如果数据库结构仍然不工作,您需要再次检查它。

useEffect(() => { 
const fetchData = async () => {
    try {
        const response = await fetch("http:localhost:4000/api/jobs", {
           credentials: "include", //to be able to send with cookies...
        });
        if(response.ok) {
            const newData = await response.json();
            console.log(newData);
            setName(newData.data.jobs.name); // this part you need to check your data structure again...
        }
    } catch (error) {
        console.log(error)
    }
  }  
    fetchData();
}, []);

可选注解:这部分不是您问题的一部分,只是以防cookie-session和jwtoken仍然存在问题,您可以更改JWT在cookie中的存储方式:cookie-session的目的是创建一个“session id”,通过在客户端(在浏览器上,与cookie一起)存储它来验证用户,如果你打算使用jwt token来验证,我真的不明白使用这个的意义?如果你仍然停留在这一部分,我让你看下面的步骤:

首先,您可能需要安装cookie解析器中间件,因为如果此方法对您有效,您将能够卸载cookie会话。

const cookieParser = require('cookie-parser')
/...
app.use(cookieParser());

在auth.controllers.js上

const loginAuth = async (req, res) => {
    try {
      const token = await authServices.login(req.body);
      // set the jwt token on the cookie
      res.cookie("jwt", token, {
        maxAge: 24 * 60 * 60 * 1000,
        httpOnly: true,
        sameSite: false, //set this to "None" if you deploy to production on cross domaine.
        secure: false,  //set to true is required on production with https
    }) 
        return res.status(200).json({
        //controller will return this message if the body sent was match
        message: "User logged in successfully!",
        });
    } catch (error) {
      //ratther it will return this erroe message
      return res.status(500).json({ message: error.message });
    }
  };

   //create a logout session for the user to logout by signing session to null
    const logoutAuth = async (req, res) => {
        res.clearCookie("jwt")
        return res.status(200).send({ message: "User logged out successfully!" });
    };

您还需要将activeAuth函数中的const token = req.session.token;以及auth中间件函数的auth.middleware.js中的const token = req.session.token;替换为:

const token = req.cookies["jwt"]  //or
 const token = req.cookies.jwt

最后,如果它的工作,你可以卸载cookie-session.

相关问题