JSON解析异常:Unexpected token <错误排查求助(附Angular代码)
这个错误其实很常见——它意味着你的代码尝试解析的内容根本不是JSON,而是HTML(因为HTML的开头几乎都是<字符,比如<html>或者错误页面的<!DOCTYPE>)。通常是你的API请求没有返回预期的JSON响应,反而返回了错误页面(比如404找不到、500服务器内部错误)。结合你提供的PostProvider代码,我给你一步步排查的思路:
1. 先确认API端点是否能正常返回JSON
直接在浏览器里(或者用Postman、curl这类工具)访问你的完整API地址(比如http://localhost/IonicFYP/server.api/[你调用postData时传的file参数]),如果是POST请求,就模拟一个POST请求,看看返回的内容是什么:
- 如果返回的是HTML页面(比如404页面),说明你的后端路径配置有问题,或者后端服务没正确处理这个请求。
- 如果返回的是JSON,那再往下排查。
2. 检查后端服务是否正常运行
确保你的http://localhost/IonicFYP/server.api/对应的后端服务已经启动,并且监听在正确的端口上。如果后端没启动,请求会直接得到浏览器默认的404错误页面,自然解析不了JSON。
3. 验证请求格式与后端的兼容性
你的代码里设置了Content-Type: application/json,并把请求体转成了JSON字符串。要确认后端是否配置了解析JSON请求体的能力:
- 比如如果是PHP后端,需要确保用
file_get_contents('php://input')来读取JSON,而不是依赖$_POST(因为$_POST只处理表单格式的数据)。 - 如果后端没配置解析JSON的中间件,可能会返回错误页面,导致你拿到HTML内容。
4. 临时添加日志,查看实际响应内容
修改你的postData方法,先打印出响应的原始文本,这样能明确知道后端返回的到底是什么:
import { Injectable } from '@angular/core'; import { Http, Headers, RequestOptions } from '@angular/http'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/catch'; import { Observable } from 'rxjs/Observable'; @Injectable() export class PostProvider { server: string = "http://localhost/IonicFYP/server.api/" constructor(public http: Http){ } postData(body, file){ let type = "application/json; charset=UTF-8"; let headers = new Headers({ 'Content-Type': type }); let options = new RequestOptions({ headers: headers}); return this.http.post(this.server + file, JSON.stringify(body), options) .map(res => { // 打印原始响应文本,排查问题 const responseText = res.text(); console.log('Backend Response:', responseText); try { return JSON.parse(responseText); } catch (e) { console.error('Failed to parse JSON:', e); throw new Error('Received non-JSON response from server'); } }) .catch(err => { console.error('Request Error:', err); return Observable.throw(err); }); } }
运行代码后看控制台的日志,就能清楚看到后端返回的是错误页面还是其他内容,进而针对性解决。
5. 排查跨域问题(可能性稍低,但也要注意)
如果你的前端运行在不同端口(比如Ionic默认的8100端口),而后端在80端口,可能存在跨域问题。虽然这个错误不是典型的CORS错误,但如果后端没配置CORS允许前端访问,也可能返回错误页面。可以检查浏览器控制台是否有CORS相关的报错。
按照这些步骤排查,应该能很快找到问题所在。
内容的提问来源于stack exchange,提问作者Azhar Mustapha

