Node.js本地服务器Axios POST请求报错排查求助
Node.js本地服务器POST请求问题排查
我是Node.js新手,在使用Axios向Node.js本地服务器发送POST请求时出现错误,无法定位问题根源。
错误说明
错误截图显示请求返回400状态码,同时存在跨域配置缺失、后端逻辑缺陷等问题。
后端代码(Server.js)
const http = require('http'); class InMemoryDatabase { constructor() { this.data = []; } // 向数据库添加对象 add(object) { this.data.push(object); } // 更新数据库中的对象 update(id, object) { const index = this.findIndexById(id); if (index !== -1) { this.data[index] = Object.assign(this.data[index], object); } } // 删除数据库中的对象 delete(id) { const index = this.findIndexById(id); if (index !== -1) { this.data.splice(index, 1); } } // 获取数据库中所有对象 getAll() { return this.data; } // 根据ID获取数据库中的对象 getById(id) { const index = this.findIndexById(id); if (index !== -1) { return this.data[index]; } } // 按筛选条件查询数据库中的对象 search(filter) { return this.data.filter(object => { for (const key in filter) { if (filter[key] !== object[key]) { return false; } } return true; }); } // 根据ID查找对象在数据库中的索引 findIndexById(id) { return this.data.findIndex(object => object.id === id); } } // 创建数据库实例 const db = new InMemoryDatabase(); // 创建Web服务器 const server = http.createServer((req, res) => { if (req.method === 'GET' && req.url === '/') { // 返回数据库中所有对象的JSON格式数据 res.setHeader('Content-Type', 'application/json'); // 添加CORS头 res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); res.write(JSON.stringify(db.getAll())); res.end(); } else if (req.method === 'GET' && req.url.startsWith('/object/')) { // 根据ID返回单个对象的JSON格式数据 const id = parseInt(req.url.split('/')[2]); const object = db.getById(id); if (object) { res.setHeader("Content-Type", "application/json, text/plain, */*"); res.write(JSON.stringify(object)); } else { res.statusCode = 404; } res.end(); } else if (req.method === 'POST' && req.url === '/') { // 向数据库添加新对象 let data = ''; req.on('data', chunk => { data += chunk; }); req.on('end', () => { try { const object = JSON.parse(data); const id = db.add(object); res.setHeader("Content-Type", "application/json, text/plain, */*"); res.setHeader('Location', `/object/${id}`); res.statusCode = 201; res.write(JSON.stringify({ id })); } catch (err) { res.statusCode = 400; } res.end(); }); } else { res.statusCode = 404; res.end(); } }); // 在8080端口启动Web服务器 server.listen(8080, () => { console.log('Web服务器已在8080端口启动'); });
前端代码(App.js)
import React, { useState, useEffect } from 'react'; import axios from 'axios'; import { Table, Button, Modal, Form } from 'react-bootstrap'; function App() { const [data, setData] = useState([]); const [showModal, setShowModal] = useState(false); const [formData, setFormData] = useState({ name: '', email: '', phone: '' }); useEffect(() => { axios.get("http://localhost:8080").then((response) => { console.log(response.data) setData(response.data); }) }, []); const handleFormChange = (event) => { const { name, value } = event.target; setFormData((prevFormData) => ({ ...prevFormData, [name]: value })); }; const handleFormSubmit = (event) => { event.preventDefault(); axios .post("http://localhost:8080", { name: "melvin", email: "test", phone: "test", }) .then((response) => { console.log(response.data); }) .catch((error) => console.log(error)); setShowModal(false); }; const handleDelete = (id) => { axios.delete(`/api/data/${id}`).then(() => { setData(data.filter((item) => item.id !== id)); }); }; return ( <div> <Table striped bordered hover> <thead> <tr> <th>Name</th> <th>Email</th> <th>Phone</th> <th>Action</th> </tr> </thead> <tbody> {data.map((item) => ( <tr key={item.id}> <td>{item.name}</td> <td>{item.email}</td> <td>{item.phone}</td> <td> <Button variant="danger" onClick={() => handleDelete(item.id)}> Delete </Button> </td> </tr> ))} </tbody> </Table> <Button variant="primary" onClick={() => setShowModal(true)}> Add Item </Button> <Modal show={showModal} onHide={() => setShowModal(false)}> <Modal.Header closeButton> <Modal.Title>Add Item</Modal.Title> </Modal.Header> <Modal.Body> <Form onSubmit={handleFormSubmit}> <Form.Group controlId="name"> <Form.Label>Name</Form.Label> <Form.Control type="text" name="name" placeholder="Enter name" value={formData.name} onChange={handleFormChange} required /> </Form.Group> <Form.Group controlId="email"> <Form.Label>Email</Form.Label> <Form.Control type="email" name="email" placeholder="Enter email" value={formData.email} onChange={handleFormChange} required /> </Form.Group> <Form.Group controlId="phone"> <Form.Label>Phone</Form.Label> <Form.Control type="text" name="phone" placeholder="Enter phone number" value={formData.phone} onChange={handleFormChange} required /> </Form.Group> <Button variant="primary" type="submit"> Add </Button> </Form> </Modal.Body> </Modal> </div> ); } export default App;
问题修复点
后端(Server.js)
- 全局配置CORS:当前仅GET请求设置了CORS头,需在所有响应前统一配置,并处理OPTIONS预检请求:
// 全局设置CORS头 res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); // 处理OPTIONS预检请求 if (req.method === 'OPTIONS') { res.writeHead(200); res.end(); return; }
- 修复
add方法返回值:当前add方法未返回ID,导致后续逻辑获取undefined,修改为自动生成唯一ID并返回:
add(object) { const newObject = { id: Date.now(), ...object }; // 用时间戳生成唯一ID this.data.push(newObject); return newObject.id; }
- 修正Content-Type格式:所有返回JSON的接口,Content-Type应设为
application/json,而非多值拼接格式:
res.setHeader('Content-Type', 'application/json');
- 完善错误处理:JSON解析失败时,返回明确的错误信息:
catch (err) { res.statusCode = 400; res.setHeader('Content-Type', 'application/json'); res.write(JSON.stringify({ error: 'JSON格式无效' })); }
- 添加DELETE接口支持:补充删除逻辑的后端实现:
else if (req.method === 'DELETE' && req.url.startsWith('/object/')) { const id = parseInt(req.url.split('/')[2]); db.delete(id); res.statusCode = 204; res.end(); }
前端(App.js)
- 使用用户输入的表单数据:替换
handleFormSubmit中硬编码的测试数据,使用用户输入的formData:
axios.post("http://localhost:8080", formData)
- 修复删除请求地址:后端删除接口路径为
/object/:id,修正请求地址:
axios.delete(`http://localhost:8080/object/${id}`)
- POST成功后更新前端数据:在POST请求回调中重新拉取数据,更新页面列表:
.then((response) => { console.log(response.data); // 重新获取数据更新列表 axios.get("http://localhost:8080").then(res => setData(res.data)); })
内容的提问来源于stack exchange,提问作者melvin debot
相关产品推荐
相关产品推荐

