【发布时间】:2021-10-15 08:34:03
【问题描述】:
我在使用 axios 发布请求时遇到问题。在浏览器中,如果我在控制台中选中“网络”,则会显示错误“401 - 未授权”。但是用 Postman 进行测试一切正常。 我已经尝试了几个在类似问题中公开的解决方案,但都没有成功。
这是我设置快递服务器的代码:
import express from "express";
import mongoose from "mongoose";
import cors from "cors";
import dotenv from "dotenv";
import authRouter from "./routes/auth.js";
import categoryRouter from "./routes/category.js";
//DOTENV CONFIG
dotenv.config();
const MONGODB_CONNECTION = process.env.MONGO_URI;
//INITIALIZE APP
const app = express();
//MIDDLEWARES
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(cors());
//ROUTES
app.use("/api/auth", authRouter);
app.use("/api/categories", categoryRouter);
//PORT
const PORT = process.env.PORT || 5020;
//CONNECT MONGODB
const connectDB = () => {
mongoose
.connect(MONGODB_CONNECTION, {
useNewUrlParser: true,
useFindAndModify: true,
useUnifiedTopology: true,
useCreateIndex: true,
})
.then(() => console.log("MONGODB is connected"))
.catch((err) => console.log("MONGODB connection error:", err));
};
connectDB();
//INITIALIZE SERVER
app.listen(PORT, () =>
console.log(`Connection is established and running on port ${PORT}`)
);
这是与路由器设置相关的代码:
import express from "express";
import { getCategories, createCategory } from "../controllers/category.js";
import { authMiddleware, authAdminMiddleware } from "../middlewares/auth.js";
const router = express.Router();
router.route("/get-categories").get(getCategories);
router
.route("/create-category")
.post(authMiddleware, authAdminMiddleware, createCategory);
export default router;
用于身份验证的中间件:
import jwt from "jsonwebtoken";
import dotenv from "dotenv";
import { User } from "../models/User.js";
dotenv.config();
const JWT_SECRET = process.env.JWT_SECRET;
export const authMiddleware = async (req, res, next) => {
try {
let token;
if (
req.headers.authorization &&
req.headers.authorization.startsWith("Bearer")
) {
token = req.headers.authorization.split(" ")[1];
}
if (!token) {
return res.status(401).json({ errorMessage: "Invalid Authentication" });
}
const decoded = jwt.verify(token, JWT_SECRET);
const user = await User.findById(decoded.user._id);
if (!user) {
return res.status(404).json({ errorMessage: "No user found" });
}
req.user = user;
next();
} catch (error) {
return res.status(500).json({ errorMessage: "Not authorized" });
}
};
export const authAdminMiddleware = async (req, res, next) => {
try {
const user = await User.findOne({
_id: req.user.id,
});
if (req.user.role === 0) {
return res
.status(400)
.json({ errorMessage: "Not Authorized. Admin private route." });
}
next();
} catch (error) {
return res
.status(401)
.json({ errorMessage: "Not Authorized. Admin private route." });
}
};
POST 请求控制器:
import { Category } from "../models/Category.js";
import slugify from "slugify";
export const createCategory = async (req, res) => {
const { name, parentId } = req.body;
try {
if (!name) {
return res
.status(400)
.json({ errorMessage: "Category name field is required." });
}
const category = await Category.findOne({ name });
if (category) {
return res.status(409).json({ errorMessage: "Category already exist." });
}
let id;
if (parentId) {
const findParentId = await Category.findOne({ name: parentId });
if (findParentId) {
id = findParentId._id;
}
}
const newCategory = new Category({
name,
slug: slugify(name),
parentId: id,
});
newCategory.save((err, saved) => {
if (err) {
return res.status(400).json({ errorMessage: err.message });
}
if (saved) {
return res
.status(201)
.json({ successMessage: "Category created successfully!" });
}
});
} catch (error) {
res.status(500).json({ errorMessage: error.message });
}
};
前端的 API 调用:
import axios from "axios";
import { getCookies } from "../helpers/storage&cookies/storage&cookies";
console.log(getCookies("token"));
const config = {
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + getCookies("token"),
},
};
export const postCategory = async (data) => {
const response = await axios.post(
"http://localhost:5020/api/categories/create-category",
data,
config
);
return response;
};
具体的客户端发布请求:
import React, { useState } from "react";
import CreateCategoryModalUI from "./CreateCategoryModalUI";
import { postCategory } from "../../../api/category";
const CreateCategoryModal = ({ categories }) => {
const [createCategoryData, setCreateCategoryData] = useState({
name: "",
parentId: "",
errorMessage: "",
successMessage: "",
loading: false,
});
const { name, parentId, successMessage, errorMessage, loading } =
createCategoryData;
const handleChange = (e) => {
if (e.target.type == "text") {
setCreateCategoryData({
...createCategoryData,
name: e.target.value,
successMessage: "",
errorMessage: "",
});
} else {
setCreateCategoryData({
...createCategoryData,
parentId: e.target.value,
errorMessage: "",
successMessage: "",
});
}
};
const handleSubmit = (e) => {
e.preventDefault();
if (!name) {
setCreateCategoryData({
...createCategoryData,
errorMessage: "Category name field is required.",
});
} else {
const data = { name, parentId };
console.log(data);
setCreateCategoryData({
...createCategoryData,
loading: true,
});
postCategory(data)
.then((response) => {
setCreateCategoryData({
name: "",
parentId: "",
errorMessage: "",
successMessage: response.data.successMessage,
loading: false,
});
})
.catch((error) => {
if (error.response.status === 409) {
setCreateCategoryData({
...createCategoryData,
errorMessage: "Category already exists",
loading: false,
});
} else {
setCreateCategoryData({
...createCategoryData,
errorMessage: error.toString(),
loading: false,
});
}
});
}
};
return (
<CreateCategoryModalUI
createCategoryData={createCategoryData}
categories={categories}
handleChange={handleChange}
handleSubmit={handleSubmit}
/>
);
};
export default CreateCategoryModal;
我该如何解决这个问题? 非常感谢!
【问题讨论】:
-
使用您的浏览器开发工具 Network 面板检查请求。
Authorization标头中是否有正确的不记名令牌?此外,如果您使用cors包,则无需手动设置 CORS 响应标头 -
是的,我已经检查过了:授权标头是正确的。此外,我还手动设置了 CORS 响应标头,因为对于另一个 POST 请求,我遇到了类似的问题,通过添加这两行代码莫名其妙地解决了。
标签: node.js express axios postman mern