Angular 4:无法从响应中读取标头 - 不是 CORS 问题 [英] Angular 4: unable to read headers from response - not a CORS issue

查看:21
本文介绍了Angular 4:无法从响应中读取标头 - 不是 CORS 问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在服务器自动更新令牌的上下文中,我在基础知识方面苦苦挣扎:从响应中获取标头数据.

In the context of a server automatically renewing a token, I'm struggling with the basics: Obtaining header data from a response.

它似乎与 CORS 无关,因为我的 Node/express 都是授权/x-access-token 并相应地响应(请参阅下面的网络选项卡屏幕).

It does not seem to be CORS related as my Node/express allwos the Authorization/x-access-token and reponds accordingly (see network tab screeencap below).

我希望看到的第一步是简单地从响应中读取标头.查看我的代码,它是文档中的样板文件.事件获取内容长度"返回空值.

The first step I want to see working is simply reading the header from the response. See my code, it's boilerplate as found in the docs. Event getting "Content-Length" returns null.

auth-service.ts

login(username:string, password:string):Observable<boolean>{
    this.loggedIn = false;
    return new Observable( (observer:Observer<boolean>) => {

      const body = {user: username, pwd: password};
      const url = this.config.API_ENDPOINT_PUBLIC_AUTH;

      this.httpClient.post(url, body, {
        responseType: 'text',
        observe: "response"
      }).first().subscribe(
        (response:HttpResponse<string>) => {

          // DEBUG
          console.log(response.headers.get('Authorization'));
          console.log(response.headers.get('X-Test-Header'));
          console.log(response.headers.get('Content-length'));


          this.token = response.headers.get('Authorization');
          this.storeToken(this.token);
          this.currentUser = username;
          this.loggedIn = true;
          this.authChanged$.next('auth');
          observer.next(true);
        },
        (err) => observer.next(false),
        () => {},
      );
    });
  }

控制台输出:

将此与此请求的网络选项卡的内容进行比较:

Compare this to the contents of my network tab for this request:

不用说我的 HttpInterceptor 也不起作用 - 在提供授权"后响应中的标头,它使用该值作为新标记.这是为了实现令牌的自动更新:

Needless to say my HttpInterceptor doesn't work either - upon being provided "Authorization" header in a response, it uses the value as new token. This to implement auto-renewal of tokens:

token.interceptor.ts

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    const authService = this.injector.get(AuthService);
    const token = authService.getToken();

    if(token){
      request = request.clone({
        setHeaders: { 'x-access-token' : token }
      });
    }
    
    return next.handle(request).do(
      (event: HttpEvent<any>) => {
        if (event instanceof HttpResponse) {
          const response:HttpResponse<any> = (<HttpResponse<any>> event);
          const authorizationHeader = response.headers.get('Authorization');
          console.log('Authorization header value: ' + authorizationHeader);
          if(authorizationHeader){
            authService.setToken(authorizationHeader);
          }
        }
      },
      (err: any) => {
      if (err instanceof HttpErrorResponse){
        if (err.status === 401) {
          this.router.navigate(['/']);
        }
      }
    });
  }

推荐答案

好的,答案在这里:我使用 Node.js/Express 作为后端,即使在 Chrome 的网络选项卡中可以看到标题,它也不会不要让它们可供 Angular 处理.

Ok, here is the answer: I'm using Node.js/Express as backend and even though headers are visible in the network tab of Chrome, it doesn't make them available for processing by Angular.

为什么它们是可见的,但不能使用?"我还不清楚.

"How comes they're visible yet cannot be used?" is still not clear to me.

配置您的 Node/Express 应用程序(查找此处的解决方案"评论):

Configure your Node/Express app (look for the comment "SOLUTION HERE"):

function configureExpress(expressApp){  
    expressApp.use(bodyparser.urlencoded({ extended: true }));
    expressApp.use(bodyparser.json());

    // Middleware: Use CORS, add headers and allow methods
    expressApp.use(expressMiddleware);
}

function expressMiddleware(req, res, next) {

    // Request origin: Allow ALL
    res.header("Access-Control-Allow-Origin", "*");

    // Allowed headers
    res.header("Access-Control-Allow-Headers",

        "Origin"
        +",X-Requested-With"   // Dont allow AJAX CORS without server consent - see http://stackoverflow.com/questions/17478731/whats-the-point-of-the-x-requested-with-header
        +",x-access-token"
        +",Content-Type"
        +",Authorization"
        +",Accept"
    );

    // SOLUTION HERE
    // Allow headers access
    res.header("access-control-expose-headers",
        ",Authorization"
        +",Content-Length"
        );

    // Allowed methods
    res.header('Access-Control-Allow-Methods',
        'GET,'
        +',POST'
        +',OPTIONS'
        +',PUT,'
        +',DELETE'
    );

    // Handle CORS requests: cross-domain/origin requests will begin with an OPTION request to the same endpoint.
    if('OPTIONS' === req.method){
        res.sendStatus(200);
    }

    else{
        // Request validations complete
        next();
    }
}

这篇关于Angular 4:无法从响应中读取标头 - 不是 CORS 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆