Node.js+React+PostgreSQL项目API取数异常:后端有数据前端无返回
Hey there! Let's break down what's going on here and fix those issues step by step. I see two main problems stopping your browser from getting the data, plus a minor optimization we can make.
1. 核心问题分析
跨域请求被浏览器拦截(CORS)
Your React app is probably running on a different port (like localhost:3000) than your Node server (localhost:8080). Browsers block cross-origin requests by default, so even if your server logs the data, the browser won't let your frontend access it unless you configure CORS on the server.
响应顺序错误(empdetails_id函数)
In your empdetails_id function, you're calling res.send() immediately before running the database query. This sends a response to the frontend right away, and the subsequent database fetch never gets passed to the browser.
不必要的重复数据库同步
You're running connection.sync() inside every request handler. This forces Sequelize to sync your model with the database on every request, which is inefficient and unnecessary.
2. 修改后的代码
第一步:更新server.js(添加CORS支持)
First, install the restify CORS middleware:
npm install restify-cors-middleware
Then update your server file:
var restify = require('restify') const corsMiddleware = require('restify-cors-middleware') const { empdetails, empdetails_id } = require('./Function'); // Configure CORS to allow your React frontend const cors = corsMiddleware({ origins: ['http://localhost:3000'], // Replace with your React app's actual URL allowHeaders: ['Content-Type'], exposeHeaders: ['Content-Type'] }) var server = restify.createServer() // Handle preflight OPTIONS requests server.pre(cors.preflight) // Apply CORS rules to all requests server.use(cors.actual) server.get('/empdetails', empdetails) server.get('/empdetails_id/:id', empdetails_id) server.listen(8080, function(){ console.log("server started on port 8080...") })
第二步:修复function.js(响应逻辑+优化同步)
var Sequelize = require('sequelize') const connection = new Sequelize('mydb', 'postgres', '123456', { host: 'localhost', dialect: 'postgres' }); var Emp = connection.define('emp',{ fullName: { type: Sequelize.STRING }, email: { type: Sequelize.STRING } }) // Sync database ONCE when the server starts, not on every request connection.sync() .then(() => console.log('Database synced successfully')) .catch(err => console.error('Error syncing database:', err)) module.exports ={ empdetails: function empdetails(req,res,next){ Emp.findAll() .then(function(emps){ console.log(emps) res.send(emps); next(); // Tell restify we're done handling this request }) .catch(err => { console.error('Error fetching employees:', err) res.status(500).send({ error: 'Failed to fetch employee details' }) next(); }) }, empdetails_id: function empdetails_id(req,res,next){ const empId = req.params.id; Emp.findByPk(empId) .then(function(emp){ if (!emp) { return res.status(404).send({ error: 'Employee not found' }) } console.log(emp) res.send(emp); next(); }) .catch(err => { console.error('Error fetching employee by ID:', err) res.status(500).send({ error: 'Failed to fetch employee details' }) next(); }) }, };
3. 关键修改说明
- CORS配置: This tells the browser it's safe to let your React app access the API from a different port.
- Fixed response order: In
empdetails_id, we now send the response only after we get data from the database. - Single database sync: Running
connection.sync()once at server startup avoids redundant work on every request. - Error handling: Added catch blocks to return meaningful error messages to the frontend, making debugging easier.
next()calls: Restify requires you to callnext()to finish processing a request, preventing hanging connections.
4. 最后检查
- Make sure your React frontend is requesting the correct URLs:
http://localhost:8080/empdetailsandhttp://localhost:8080/empdetails_id/[your-id]. - Double-check that your PostgreSQL database is running and the
mydbdatabase exists with theemptable.
内容的提问来源于stack exchange,提问作者Prathamesh Jadhav

