React+Axios调用Node/Express接口遇权限、网络错误及端口占用问题求助
问题排查与代码修复方案
一、核心错误分析与修复
1. 数据库权限错误(ER_ACCESS_DENIED_ERROR)
原因:db.js中创建连接池时直接传入了整个config对象,但配置里的数据库参数嵌套在db字段下,导致mysql模块无法读取正确的用户名、密码,默认用空用户发起连接,触发权限拒绝。
修复后的db.js:
const mysql = require("mysql"); const config = require("./config"); // 传入config.db而非整个config对象 var con = mysql.createPool(config.db); module.exports = con;
2. Axios Network Error
常见触发原因及解决:
- 后端服务未正常启动:确保Express服务在8000端口运行,控制台能看到
Running on port :8000日志 - 前端请求地址错误:Axios请求需指向
http://localhost:8000(端口与后端保持一致) - 请求体解析问题:后端未配置JSON解析,POST请求无法接收参数,需在
index.js中添加app.use(express.json())
3. MySQL 3306端口占用问题
- 可选替代端口:3307、3308、3309都是常用的MySQL备用端口
- 修改MySQL配置:找到my.cnf(Windows为my.ini),修改
port=3307后重启MySQL服务 - 临时解决:杀死占用3306的进程(Windows用
netstat -ano | findstr 3306找PID,再taskkill /PID [PID] /F;Linux用lsof -i :3306后kill -9 [PID])
二、全文件代码优化
config.js(格式化代码)
const config = { db: { host: "localhost", user: "new_user", password: "password", database: "db" } }; module.exports = config;
index.js(修复中间件,清理冗余)
const express = require("express"); const cors = require("cors"); const app = express(); // 解析JSON请求体,POST请求必须配置 app.use(express.json()); // 细化CORS配置,生产环境限定前端地址 app.use(cors({ origin: "http://localhost:3000" })); // 替换为你的前端实际地址 const TablesRoutes = require("./routes/TablesRoutes"); app.use("/", TablesRoutes); // 优先使用环境变量端口,本地默认8000 const PORT = process.env.PORT || 8000; app.listen(PORT, () => { console.log(`Running on port :${PORT}`); });
TablesRoutes.js(完善路由配置)
const express = require("express"); const { postTableDes, alterTable, showTables, } = require("../Controllers/Tables"); const tablerouter = express.Router(); tablerouter.get("/", showTables); tablerouter.post("/", postTableDes); // 补充alterTable对应的路由(示例) // tablerouter.put("/:tableName", alterTable); module.exports = tablerouter;
Tables.js(修复回调冲突,支持async/await)
推荐改用mysql2/promise(原生支持Promise,适配async/await)
先安装依赖:npm install mysql2
修改后的Tables.js:
const mysql = require("mysql2/promise"); const config = require("../Config/config").db; // 创建mysql2连接池 const pool = mysql.createPool(config); // 获取所有表 const showTables = async (req, res) => { try { const [rows] = await pool.query("SHOW TABLES"); res.status(200).json({ tables: rows }); } catch (err) { console.error(err); res.status(500).json({ error: "获取表列表失败" }); } }; // 示例POST创建表逻辑 const postTableDes = async (req, res) => { try { const { tableName, columns } = req.body; // 参数化查询避免SQL注入 const createSql = `CREATE TABLE IF NOT EXISTS ?? (?)`; await pool.query(createSql, [tableName, columns]); res.status(201).json({ message: "表创建成功" }); } catch (err) { console.error(err); res.status(500).json({ error: "创建表失败" }); } }; // 示例修改表结构逻辑 const alterTable = async (req, res) => { try { const { tableName, alterSql } = req.body; await pool.query(`ALTER TABLE ?? ${alterSql}`, [tableName]); res.status(200).json({ message: "表结构修改成功" }); } catch (err) { console.error(err); res.status(500).json({ error: "修改表结构失败" }); } }; // 导出所有控制器函数 module.exports = { showTables, postTableDes, alterTable };
三、更佳实现建议
环境变量管理:用
dotenv存储敏感配置,避免硬编码- 安装:
npm install dotenv - 创建
.env文件:DB_HOST=localhost DB_USER=new_user DB_PASSWORD=password DB_NAME=db PORT=8000 - 在config.js中引入:
require("dotenv").config(); const config = { db: { host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME } };
- 安装:
全局错误处理:在index.js添加统一错误捕获中间件
app.use((err, req, res, next) => { console.error(err.stack); res.status(500).json({ error: "服务器内部错误" }); });SQL注入防护:所有数据库操作使用参数化查询,禁止直接拼接SQL语句
前端Axios配置:创建Axios实例统一配置基础URL
import axios from "axios"; const api = axios.create({ baseURL: "http://localhost:8000", timeout: 10000 });
内容的提问来源于stack exchange,提问作者prathmesh
相关产品推荐
相关产品推荐

