Unexpected token '<', "<!DOCTYPE "... is not valid JSON 错误解析与解决
问题概述
当在 React 应用中进行数据获取时,开发者可能会遇到 SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
错误。这个错误表明你的应用试图将 HTML 内容解析为 JSON 格式,而这两种格式在语法上完全不兼容。
错误原因分析
这个错误通常发生在以下几种情况:
- API 端点 URL 错误 - 尝试访问不存在的 API 端点
- 路径配置问题 - 前后端服务端口不匹配或路径配置错误
- JSON 文件路径错误 - 本地 JSON 文件路径引用不正确
- 服务器配置问题 - 后端路由配置不当
- 缺少必要的请求头 - 没有正确设置 Accept 头部
解决方案
1. 检查 API 端点 URL
最常见的错误原因是 URL 拼写错误或端口不匹配:
// 错误示例:端口或路径不正确
const response = await fetch("http://localhost:3000/blogs/" + id);
// 正确示例:确保端口与后端服务一致
const response = await fetch("http://localhost:8000/blogs/" + id);
TIP
始终在浏览器中直接访问 API URL 来验证它是否返回 JSON 数据,而不是 HTML 页面。
2. 验证本地 JSON 文件路径
当从公共目录引用本地 JSON 文件时:
// 错误示例:路径可能不正确
fetch('./movies.json')
// 正确示例:使用相对于 public 目录的路径
fetch('../movies.json')
3. 配置服务器端路由
对于 Node.js + Express 后端,确保正确配置静态文件服务和通配符路由:
// 生产环境配置
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, "client", "build")));
// API 路由应在通配符路由之前定义
app.get('/api/data', (req, res) => {
res.json({ message: "数据内容" });
});
// 通配符路由应放在最后
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "client", "build", "index.html"));
});
}
4. 设置正确的请求头
确保 fetch 请求包含正确的 Accept 头部:
const response = await fetch(url, {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});
5. 使用代理解决跨域问题
在开发环境中,可以在 package.json 中配置代理:
{
"proxy": "http://localhost:3001",
"dependencies": {
// 依赖项...
}
}
6. 添加错误处理
始终使用 try-catch 块处理可能的错误:
try {
const response = await fetch("http://localhost:8000/data");
const data = await response.json();
// 处理数据...
} catch (error) {
console.error("获取数据失败:", error);
// 适当的错误处理逻辑
}
调试技巧
- 使用开发服务器:运行
npm start
而不是npm run build
,以便在浏览器控制台中看到更详细的错误信息 - 检查网络请求:使用浏览器开发者工具的 Network 选项卡查看实际请求和响应
- 验证 JSON 格式:确保响应的确实是有效的 JSON 数据
总结
Unexpected token '<'
错误通常表示你的应用收到了 HTML 响应而不是期望的 JSON 数据。通过仔细检查 API 端点、路径配置、服务器设置和请求头,你可以快速定位并解决这个问题。始终添加适当的错误处理代码,以便更好地诊断和解决问题。