Angular调用Symfony接口报JSON解析错误:Unexpected token < 求解
这个错误我之前也碰到过,核心原因是接口返回的不是合法JSON,而是HTML内容(比如权限验证失败的页面、Symfony服务器错误页)——JSON解析器遇到第一个字符是<自然就报错了。结合你的代码和场景,咱们一步步排查解决:
1. 先确认接口实际返回的内容
别光看请求状态码,打开浏览器开发者工具的Network面板,找到这个POST请求,切换到Response标签,看看返回的到底是什么HTML:
- 如果是401/403相关的HTML页面:说明权限验证失败,Symfony返回了默认的错误页而非JSON
- 如果是500错误的HTML:说明Symfony后端执行出错,比如JWT验证失败、序列化错误或者数据库操作异常
- 如果是重定向的HTML:可能是Symfony把未授权请求重定向到了登录页
这一步是定位问题的关键,一定要先看清楚返回的HTML内容。
2. 检查Authorization Token的有效性
你的Angular代码里通过Bearer + token设置了授权头,这里要确认:
this.authenticationService.token是不是正确的JWT字符串?有没有过期?可以用JWT解码工具验证一下- 浏览器Request Headers里的
Authorization头格式是否正确?应该是Bearer xxxxxxxxxx(注意Bearer后面有个空格) - 把这个token复制到Postman里,模拟同样的请求,看是否能正常返回JSON——如果Postman用这个token也报错,那就是token本身的问题
3. 确保Symfony权限验证失败时返回JSON
如果是权限问题(比如token无效、用户无权限),Symfony默认可能返回HTML错误页,你需要配置让它返回JSON响应。比如用LexikJWTAuthenticationBundle的话,在security.yml里配置:
security: firewalls: api: pattern: ^/api stateless: true guard: authenticators: - lexik_jwt_authentication.jwt_token_authenticator # 关键:设置entry_point,确保验证失败返回JSON entry_point: lexik_jwt_authentication.jwt_token_authenticator
这样当JWT验证失败时,Symfony会返回标准的JSON格式错误响应,而不是HTML。
4. 优化Angular的请求代码(可选但推荐)
你的Angular代码用了旧的Headers类,Angular 4+推荐用HttpHeaders,而且HttpClient会自动帮你序列化JSON对象,不用手动JSON.stringify:
import { HttpClient, HttpHeaders } from '@angular/common/http'; // ... addUser(user: User) { const headers = new HttpHeaders() .set('Content-Type', 'application/json') .set('Authorization', `Bearer ${this.authenticationService.token}`); // 直接传user对象,HttpClient会自动序列化 return this.http.post(this.uri, user, { headers }) .pipe(map(res => res.json())); }
这样可以避免手动序列化可能带来的格式问题。
5. 查看Symfony后端日志
如果是后端执行出错,打开Symfony项目的var/log/dev.log(开发环境),里面会详细记录所有异常信息:
- 比如JWT验证失败的日志
- JMS序列化时的错误(比如User实体的注解配置问题)
- Doctrine持久化时的异常(比如字段为空违反约束)
通过日志能快速定位后端代码的问题。
总结
大概率是权限验证失败导致Symfony返回HTML,或者token无效/格式错误。先看Response的HTML内容,再针对性解决权限配置或token问题,最后结合后端日志排查其他可能的异常。
内容的提问来源于stack exchange,提问作者enginer

