如何用React与Express对接MSSQL并解决前端JSON解析报错
Hey there! Let's break down what's going wrong and how to get your React + Express + MSSQL setup working smoothly to display your customer, project, and task data in tables.
First, Let's Fix That JSON Parsing Error
The Unexpected token P in JSON at position 0 error tells us your React app is trying to parse non-JSON data from the /users endpoint. That "P" is almost certainly the start of plain text or HTML (like "Page Not Found" or an error message from Express) instead of valid JSON. Here's how to debug and fix this:
Step 1: Verify Your Backend Endpoint is Working
- Open your browser and navigate directly to
http://localhost:YOUR_EXPRESS_PORT/users(replaceYOUR_EXPRESS_PORTwith whatever port your Express server uses, like 3001). - If you see anything other than clean JSON (like HTML error pages, "Cannot GET /users", or raw error text), your Express route is misconfigured.
- Make sure your Express route properly queries MSSQL and returns JSON, with error handling to avoid non-JSON responses:
// Example Express route for fetching users app.get('/users', async (req, res) => { try { // Replace with your actual MSSQL query const queryResult = await yourMSSQLPool.query('SELECT id, username FROM Customers'); // MSSQL results are typically stored in recordset res.json(queryResult.recordset); } catch (err) { console.error('Database query error:', err); // Return a JSON error instead of plain text res.status(500).json({ error: 'Failed to load user data' }); } });
Step 2: Add Error Handling to Your React Code
Your current React code doesn't handle failed requests or non-JSON responses. Let's update it to catch errors and safely render data:
import React, { Component } from 'react'; import './App.css'; class App extends Component { state = { users: [], projects: [], tasks: [], error: null }; componentDidMount() { // Fetch all three datasets at once with Promise.all Promise.all([ this.fetchData('/users'), this.fetchData('/projects'), this.fetchData('/tasks') ]) .then(([users, projects, tasks]) => { this.setState({ users, projects, tasks, error: null }); }) .catch(err => { this.setState({ error: `Failed to load data: ${err.message}` }); }); } // Reusable fetch helper with error checking fetchData(endpoint) { return fetch(endpoint) .then(res => { if (!res.ok) throw new Error(`Status: ${res.status}`); return res.json(); }); } render() { const { users, projects, tasks, error } = this.state; if (error) { return <div className="error-message">{error}</div>; } return ( <div className="App"> <h1>Customer, Project & Task Dashboard</h1> {/* Customers Table */} <h2>Customers</h2> <table border="1" cellPadding="8" cellSpacing="0"> <thead> <tr> <th>ID</th> <th>Username</th> {/* Add other customer fields as needed */} </tr> </thead> <tbody> {users.map(user => ( <tr key={user.id}> <td>{user.id}</td> <td>{user.username}</td> </tr> ))} </tbody> </table> {/* Projects Table */} <h2>Projects</h2> <table border="1" cellPadding="8" cellSpacing="0"> <thead> <tr> <th>ID</th> <th>Project Name</th> <th>Customer ID</th> </tr> </thead> <tbody> {projects.map(project => ( <tr key={project.id}> <td>{project.id}</td> <td>{project.name}</td> <td>{project.customer_id}</td> </tr> ))} </tbody> </table> {/* Tasks Table */} <h2>Tasks</h2> <table border="1" cellPadding="8" cellSpacing="0"> <thead> <tr> <th>ID</th> <th>Task Description</th> <th>Project ID</th> </tr> </thead> <tbody> {tasks.map(task => ( <tr key={task.id}> <td>{task.id}</td> <td>{task.description}</td> <td>{task.project_id}</td> </tr> ))} </tbody> </table> </div> ); } } export default App;
Step 3: Fix Cross-Origin Issues (If Needed)
If your Express server runs on a different port than React (e.g., Express on 3001, React on 3000), add a proxy to React's package.json to avoid CORS errors:
// Add this line to your package.json "proxy": "http://localhost:3001"
This tells React's development server to forward API requests to your Express backend.
内容的提问来源于stack exchange,提问作者Dervis Selimovic

