You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 4升级至Angular 5时AuthService中json()方法报错咨询

解决Angular 4升级到5时AuthService的JSON解析错误

嘿,这个问题我太熟悉了!你遇到的是Angular 5里HttpClient和老版本Http的核心差异,加上一个容易忽略的HttpHeaders使用坑,我帮你一步步解决:

核心错误原因

Angular 5引入的@angular/common/http里的HttpClient,默认会自动将响应体解析为JSON对象,不再需要像老版本Http那样手动调用.json()方法——这就是你收到Property 'json' does not exist on type 'Object'错误的原因。

另外还有一个隐藏问题:你当前的HttpHeaders写法是无效的,因为HttpHeaders是不可变对象,每次调用append()都会返回一个新的实例,而不是修改原对象,所以你的请求头其实根本没加上授权信息!

具体修改步骤

1. 移除.json()调用

把报错的这行:

user = resp.json().principal;

改成直接访问响应对象的属性:

user = resp['principal'];
// 要是想更严谨,可以定义响应类型接口,比如:
// interface LoginResponse { principal: User };
// user = (resp as LoginResponse).principal;

2. 修复HttpHeaders的赋值方式

原来的headers创建代码不会生效,改成链式调用(每次append都会返回新的headers实例):

const base64Credential: string = btoa(`${user.username}:${user.password}`);
const headers = new HttpHeaders()
  .append('Accept', 'application/json')
  .append('Authorization', `Basic ${base64Credential}`);

3. 补充:让请求真正执行(可选但关键)

你的logIn方法里调用了http.get()但没有返回Observable也没有订阅,这样请求根本不会发送!建议改成返回Observable,让组件去订阅触发请求:

public logIn(user: User): Observable<User> {
  // ... 上面的headers代码 ...
  return this.http.get('http://localhost:8081/account/login', { headers: headers}).pipe(
    map(resp => {
      user = resp['principal'];
      if (user) {
        localStorage.setItem('currentUser', JSON.stringify(user));
      }
      return user;
    })
  );
}

注:Angular 5对应的RxJS版本推荐用pipe()包裹操作符,替代旧的链式调用写法,更符合新版本规范。

修改后的完整AuthService代码

import { Injectable } from '@angular/core';
import { User } from '../model/model.user';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class AuthService {
  constructor(public http: HttpClient) { }

  public logIn(user: User): Observable<User> {
    const base64Credential: string = btoa(`${user.username}:${user.password}`);
    const headers = new HttpHeaders()
      .append('Accept', 'application/json')
      .append('Authorization', `Basic ${base64Credential}`);

    return this.http.get('http://localhost:8081/account/login', { headers: headers}).pipe(
      map(resp => {
        // 直接使用resp,HttpClient已自动解析JSON
        const loggedInUser = resp['principal'] as User;
        if (loggedInUser) {
          localStorage.setItem('currentUser', JSON.stringify(loggedInUser));
        }
        return loggedInUser;
      })
    );
  }

  logOut(): Observable<any> {
    return this.http.post('http://localhost:8081/logout', {}).pipe(
      map(resp => {
        localStorage.removeItem('currentUser');
        return resp;
      })
    );
  }
}

额外说明

  • 如果需要处理非JSON响应,可以在http.get()的选项里添加responseType: 'text'等配置,不过你的接口返回JSON,默认配置就够用。
  • 关于RxJS操作符:Angular 5之后推荐用pipe()组合操作符,这是RxJS 6+的标准写法,兼容性更好。

内容的提问来源于stack exchange,提问作者SS_FStuck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:14:24