使用axios / fetch从节点获取数据



请我需要一个关于如何从节点获取数据的帮助,我已经被困在这里2周了。

下面是我的后台代码:

server.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}`);
});

app.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中,我有两个方法我试图从节点获取数据到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, …}

而第二个方法在浏览器控制台

中不返回任何内容我正试图从我的节点后端获取数据到前端反应,但我的第一个方法日志错误,而第二个方法日志没有

我认为你需要清理一下你的设置,因为你使用的是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你把数据属性放在你的响应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的目的是创建一个"会话id";通过将用户身份存储在客户端(在浏览器上,使用cookie)来进行身份验证,如果要使用JWT令牌进行身份验证,我不认为使用这个有什么意义?如果你还在看这部分,我让你看看下面的步骤:

首先,您可能需要安装cookie解析器中间件,因为如果此方法适合您,您将能够卸载cookie-session。

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.middleware.js中的auth中间件函数中:

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

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

最新更新