简体   繁体   English

如何在 Angular 2 中正确设置 Http 请求标头

[英]How to correctly set Http Request Header in Angular 2

I have an Ionic 2 application using Angular 2, which is sending an Http PUT to a ASP.NET Core API server.我有一个使用 Angular 2 的 Ionic 2 应用程序,它向 ASP.NET Core API 服务器发送一个 Http PUT。 Here's the method I'm using to send the request:这是我用来发送请求的方法:

public update(student: Student): Promise<Student>
{
    let headers = new Headers();
    headers.append('Content-Type', 'application/json');
    headers.append('authentication', `${student.token}`);

    const url = `${this.studentsUrl}`;

    return this.http
        .put(url, JSON.stringify(student), { headers: headers })
        .toPromise()
        .then(() => student)
        .catch(this.handleError);
}

I'm setting an authentication key/value on the headers object.我正在标题对象上设置身份验证键/值。

But when I receive this request on the server, I cannot find the authentication key on the header:但是当我在服务器上收到此请求时,在标头上找不到身份验证密钥:

在此处输入图片说明

As you can see in the picture, there are many keys on the header, but not the content and authentication keys that I manually added to the header in the client application.正如您在图片中看到的,标头中有许多密钥,但没有我在客户端应用程序中手动添加到标头的内容和身份验证密钥。

What am I doing wrong?我究竟做错了什么?

Your parameter for the request options in http.put() should actually be of type RequestOptions.您在 http.put() 中请求选项的参数实际上应该是 RequestOptions 类型。 Try something like this:尝试这样的事情:

let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('authentication', `${student.token}`);

let options = new RequestOptions({ headers: headers });
return this.http
    .put(url, JSON.stringify(student), options)

Angular 4 >角 4 >

You can either choose to set the headers manually , or make an HTTP interceptor that automatically sets header(s) every time a request is being made.您可以选择手动设置标头,也可以制作一个HTTP 拦截器,在每次发出请求时自动设置标头。


Manually手动

Setting a header:设置标题:

http
  .post('/api/items/add', body, {
    headers: new HttpHeaders().set('Authorization', 'my-auth-token'),
  })
  .subscribe();

Setting headers:设置标题:

this.http
.post('api/items/add', body, {
  headers: new HttpHeaders({
    'Authorization': 'my-auth-token',
    'x-header': 'x-value'
  })
}).subscribe()

Local variable (immutable instantiate again)局部变量(不可变再次实例化)

let headers = new HttpHeaders().set('header-name', 'header-value');
headers = headers.set('header-name-2', 'header-value-2');

this.http
  .post('api/items/add', body, { headers: headers })
  .subscribe()

The HttpHeaders class is immutable, so every set() returns a new instance and applies the changes. HttpHeaders 类是不可变的,因此每个 set() 都会返回一个新实例并应用更改。

From the Angular docs .来自 Angular文档


HTTP interceptor HTTP拦截器

A major feature of @angular/common/http is interception, the ability to declare interceptors which sit in between your application and the backend. @angular/common/http 的一个主要特性是拦截,能够声明位于应用程序和后端之间的拦截器。 When your application makes a request, interceptors transform it before sending it to the server, and the interceptors can transform the response on its way back before your application sees it.当您的应用程序发出请求时,拦截器在将其发送到服务器之前对其进行转换,并且拦截器可以在您的应用程序看到它之前在返回的途中转换响应。 This is useful for everything from authentication to logging.这对于从身份验证到日志记录的所有事情都很有用。

From the Angular docs .来自 Angular 文档

Make sure you use @angular/common/http throughout your application.确保在整个应用程序中使用@angular/common/http That way your requests will be catched by the interceptor.这样你的请求就会被拦截器捕获。

Step 1, create the service:第一步,创建服务:

import * as lskeys from './../localstorage.items';
import { Observable } from 'rxjs/Observable';
import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpHeaders } from '@angular/common/http';

@Injectable()
export class HeaderInterceptor implements HttpInterceptor {

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        if (true) { // e.g. if token exists, otherwise use incomming request.
            return next.handle(req.clone({
                setHeaders: {
                    'AuthenticationToken': localStorage.getItem('TOKEN'),
                    'Tenant': localStorage.getItem('TENANT')
                }
            }));
        }
        else {
            return next.handle(req);
        }
    }
}

Step 2, add it to your module:第 2 步,将其添加到您的模块中:

providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: HeaderInterceptor,
      multi: true // Add this line when using multiple interceptors.
    },
    // ...
  ]

Useful links:有用的链接:

We can do it nicely using Interceptors .我们可以使用Interceptors很好地做到这一点。 You dont have to set options in all your services neither manage all your error responses, just define 2 interceptors (one to do something before sending the request to server and one to do something before sending the server's response to your service)您不必在所有服务中设置选项,也不必管理所有错误响应,只需定义 2 个拦截器(一个在将请求发送到服务器之前执行某些操作,另一个在将服务器响应发送到您的服务之前执行某些操作)

  1. Define an AuthInterceptor class to do something before sending the request to the server.定义一个AuthInterceptor类在将请求发送到服务器之前做一些事情。 You can set the api token (retrieve it from localStorage, see step 4) and other options in this class.您可以在此类中设置 api 令牌(从 localStorage 中检索它,参见步骤 4)和其他选项。

  2. Define an responseInterceptor class to do something before sending the server response to your service (httpClient).在将服务器响应发送到您的服务 (httpClient) 之前,定义一个responseInterceptor类来执行某些操作。 You can manage your server response, the most comon use is to check if the user's token is valid (if not clear token from localStorage and redirect to login).您可以管理您的服务器响应,最常见的用途是检查用户的令牌是否有效(如果不从 localStorage 清除令牌并重定向到登录)。

  3. In your app.module import HTTP_INTERCEPTORS from '@angular/common/http'.在您的app.module 中,从“@angular/common/http”导入 HTTP_INTERCEPTORS。 Then add to your providers the interceptors (AuthInterceptor and responseInterceptor).然后向您的提供者添加拦截器(AuthInterceptor 和 responseInterceptor)。 Doing this your app will consider the interceptors in all our httpClient calls.这样做您的应用程序将考虑我们所有 httpClient 调用中的拦截器。

  4. At login http response (use http service), save the token at localStorage.在登录 http 响应(使用http服务)时,将令牌保存在 localStorage 中。

  5. Then use httpClient for all your apirest services.然后将httpClient用于所有 Apirest 服务。

You can check some good practices on my github proyect here您可以在此处查看我的 github 项目上的一些良好实践

在此处输入图片说明

For us we used a solution like this:对我们来说,我们使用了这样的解决方案:

this.http.get(this.urls.order + '&list', {
        headers: {
            'Cache-Control': 'no-cache',
        }
    }).subscribe((response) => { ...

Reference here参考这里

这应该可以通过从 Angular 导入标头来轻松解决:

import { Http, Headers } from "@angular/http";

You have a typo.你有一个错字。

Change: headers.append('authentication', ${student.token});更改: headers.append('authentication', ${student.token});

To: headers.append('Authentication', student.token);至: headers.append('Authentication', student.token);

NOTE the Authentication is capitalized注意Authentication是大写的

The simpler and current approach for adding header to a single request is:将标头添加到单个请求的更简单和当前的方法是:

// Step 1 // 第1步

const yourHeader: HttpHeaders = new HttpHeaders({
    Authorization: 'Bearer JWT-token'
});

// POST request // POST 请求

this.http.post(url, body, { headers: yourHeader });

// GET request // 获取请求

this.http.get(url, { headers: yourHeader });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM