编辑模式提交表单遇JSON截断错误,路由跳转失效
问题分析与修复方案
嘿,我看你遇到的问题是编辑模式提交表单时控制台报两次「Unexpected end of JSON input」,虽然数据能正常存进数据库,但提交后的路由跳转却失效了对吧?核心原因其实是后端PUT接口返回了空响应,而你的前端代码硬要把空内容解析成JSON,导致报错中断了跳转逻辑。下面一步步给你解决:
1. 错误根源拆解
你看threat.service.ts里的extractData方法:
public extractData(res: any) { return res.json() || []; }
当后端处理完更新请求后,可能只返回了200状态码但响应体是空的(很多后端会这么设计),这时候res.json()就会抛出错误——因为空字符串不是合法的JSON格式,所以触发了「Unexpected end of JSON input」。
而且你的handleError里也埋了同样的坑:
const body = error.json() || '';
如果错误响应的体也是空的,这里又会触发一次解析错误,所以你会看到两次控制台报错。
更关键的是,因为Observable抛出了错误,你onSubmit里subscribe的next回调根本没机会执行,所以router.navigate就没跑起来,这就是跳转失效的直接原因。
2. 具体修复步骤
第一步:让extractData兼容空响应
修改extractData方法,先判断响应是否有内容再解析JSON:
public extractData(res: Response) { // 204是HTTP标准的"无内容"状态码,后端更新成功常返回这个 if (res.status === 204 || res.body === null) { return {}; // 或者返回null/空数组,根据你的业务需求调整 } // 先获取响应文本并判断是否为空,再决定是否解析JSON const responseText = res.text().trim(); return responseText ? res.json() : []; }
第二步:修复错误处理里的JSON解析
在handleError里添加try-catch,避免解析空错误响应时再次报错:
public handleError(error: Response | any) { let errMsg: string; if (error instanceof Response) { let body: any = ''; try { // 尝试解析JSON,失败就直接用响应文本 body = error.json() || ''; } catch (e) { body = error.text().trim() || '无详细错误信息'; } const err = body.error || JSON.stringify(body); errMsg = `${error.status} - ${error.statusText || ''} ${err}`; } else { errMsg = error.message ? error.message : error.toString(); } console.error(errMsg); return Observable.throw(errMsg); }
第三步:给subscribe添加错误回调(可选但推荐)
这样就算真的出现错误,你也能及时捕获并给用户反馈,避免页面无响应:
this.threatService.updateThreat(this.threatForm.value) .subscribe( (data) => { this.router.navigate(['/threat']); console.log('更新成功:', this.threatForm); }, (error) => { // 这里可以添加弹窗提示用户更新失败,提升体验 console.error('更新出错:', error); } )
额外小建议
- 可以跟后端同事确认下PUT接口的返回规范:最好返回更新后的Threat对象,或者明确返回204状态码,这样前端处理会更顺畅。
- 如果你的Angular版本是4.3及以上,建议换成
HttpClient代替旧的Http——它会自动处理JSON解析,对空响应的兼容性更好,代码也更简洁。
内容的提问来源于stack exchange,提问作者redux17
相关产品推荐
相关产品推荐

