【问题标题】:MEAN stack error. "Cannot set headers after they are sent to the client"平均堆栈错误。 “发送到客户端后无法设置标头”
【发布时间】:2018-11-01 23:31:25
【问题描述】:

我有一个 MEAN 堆栈应用程序正在尝试进行故障排除。我已经隔离了这个问题,但我不确定如何解决这里是代码。我认为错误所在的位置已标记为此类。

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../services/auth.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-success',
  templateUrl: './success.component.html',
  styleUrls: ['./success.component.css']
})
export class SuccessComponent implements OnInit {
  user:Object;

  constructor(
    private authService:AuthService,
    private router:Router) { }

  ngOnInit() {
    this.authService.getProfile().subscribe(profile => { //THIS CALL TO GET PROFILE CAUSES THE ERROR
      console.log("GOT HERE (IN SUCCESS)");
      this.user = profile.user;
    },
    err => {
      console.log("ERROR" + err);
      return false;
    });
  }

  onLogoutClick(){
    this.authService.logout();
    this.router.navigate(['/']);
    return false;
  }
}

这里使用 get Profile() 方法

import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import "rxjs/add/operator/map";
import { tokenNotExpired } from 'angular2-jwt';

@Injectable()
export class AuthService {
  authToken: any;
  user: any;

  constructor(private http:Http) { }

  registerUser(user) {
    let headers = new Headers();
    headers.append('Content-Type','application/json');
    return this.http.post('http://localhost:3000/users/register', user, {headers: headers}).map(res => res.json());
  }

  authenticateUser(user) {
    let headers = new Headers();
    headers.append('Content-Type','application/json');
    return this.http.post('http://localhost:3000/users/authenticate', user, {headers: headers}).map(res => res.json());
  }

  getProfile() {
    let headers = new Headers();
    this.loadToken();
    headers.append('Authorization', this.authToken);
    headers.append('Content-Type','application/json');
    console.log("GOT HERE (IN getProfile)");
    return this.http.get('http://localhost:3000/users/success', {headers: headers}).map(res => res.json()); //PROBLEM IS HERE
  }

  loadToken() {
    const token = localStorage.getItem('id_token');
    this.authToken = token;
  }

  loggedIn() {
    return tokenNotExpired('id_token');
  }

  storeUserData(token, user) {
    localStorage.setItem('id_token', token);
    localStorage.setItem('user', JSON.stringify(user));
    this.authToken = token;
    this.user = user;
    console.log("GOT HERE...");
  }

  logout() {
    this.authToken = null;
    this.user = null;
    localStorage.clear();
  }
}

任何帮助将不胜感激。我看过类似的帖子,但在这种情况下它们对我没有帮助。

这里也是路线

router.get('/success', passport.authenticate('jwt', {session:false}), (req, res, next) => {
    const user = req.user;
    console.log("GOT HERE (IN the route file)");
    return res.json({user: user});
    //return res.json({success: true, msg: 'user is found'});
});

【问题讨论】:

  • 错误看起来像这样:events.js:165 throw er; // 未处理的 'error' 事件 ^ 错误 [ERR_HTTP_HEADERS_SENT]: 发送到客户端后无法设置标头
  • loadToken() 在哪里?
  • 很抱歉没有包含整个文件
  • 尽量不回:就res.json({user: user});

标签: angular express routing mean


【解决方案1】:

您几乎做对了所有事情,但您不必从角度服务设置内容类型。 Angular 会自动为您完成这项工作。

如果您尝试将身份验证令牌与您的 api 请求一起发送,请尝试以下模式。

不要调用你的函数来为你加载令牌,而是尝试直接从你的函数调用 localstorage。

示例

getProfile() {
  const headers = new Headers()
  .set('Authorization', localStorage.getItem('id_token'));
  console.log("GOT HERE (IN getProfile)");
  return this.http.get('http://localhost:3000/users/success', {headers: headers}).map(res => res.json()); //PROBLEM IS HERE
}

或者,如果您愿意,您可以在服务文件中初始化一个变量,然后从本地存储中只获取一次该值。

token = localStorage.getItem('id_token');

更新我的答案,以便您可以使用 Angular 提供的新 HttpClient。

导入新的 HttpClient 模块,然后在构造函数中创建对象

import { HttpClient, HttpHeaders} from '@angular/common/http';

constructor(private http: HttpClient) { }

【讨论】:

  • @VirgilMartinez 是的。我在 Headers() 之后放置了一个分号,因为我错误地编辑了我的答案
  • 我收到此错误“'{ headers: void;}' 类型的参数不能分配给'RequestOptionsArgs' 类型的参数。属性'headers' 的类型不兼容。'void' 类型是不能分配给类型“标题”。”
  • const headers = new Headers().set('Authorization', localStorage.getItem('id_token'));这样做,还要确保你的令牌存在于你的本地存储中。
  • 我这样做了,但我仍然收到同样的错误。出于某种原因,它将其设置为无效。
  • 请检查您的本地存储,因为我还看到您使用的是旧的 http 尝试使用新的 import { HttpClient, HttpHeaders} from '@angular/common/http';跨度>
猜你喜欢
  • 2019-10-20
  • 1970-01-01
  • 1970-01-01
  • 2020-07-11
相关资源
最近更新 更多