实现[Angular] HTTP客户端(REST客户端)
首先
让我们来看一下如何通过Angular与后端进行通信。
我们将使用Http HttpClient服务,并确认通过REST API实现的方法。
最新的資訊
2021年8月14日
補足-3 として、レスポンスにヘッダ情報を含める設定について追記しました
2021年1月4日
- 記事内で扱ったコードを Angular v11.0.5 で確認しました
2019年3月22日 (2019 3 yuè 22 rì)
- Angular 7.2.2 の現在、Headers が非推奨となっているため、REST-API のヘッダ情報を HttpHeaders を使用するよう修正しました
2018年5月13日
-
- Angular 5.0.0 で @angular/http が非推奨( 出典:Version 5.0.0 of Angular Now Available )となったため、Httpクライアントモジュールを @angular/common/http に変更しました
- 「登録」「更新」「削除」 の動作検証を行えるよう UI を変更しました
工作环境
后端
Node.js和npm的版本要与前端一致。
前端
$ ng --version
Angular$ node --version
npm$ npm --version
$ ng版本_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | ‘_ \ / _` | | | | |/ _` | ‘__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 11.0.5
Node: 12.18.3
操作系统: darwin x64
Angular版本: 11.0.5
… 动画, CLI, 公共模块, 编译器, 编译器CLI, 核心, 表单
… 平台浏览器, 动态平台浏览器, 路由器
使用的Workspace: 是
包 版本
———————————————————
@angular-devkit/architect 0.1100.5
@angular-devkit/build-angular 0.1100.5
@angular-devkit/core 11.0.5
@angular-devkit/schematics 11.0.5
@schematics/angular 11.0.5
@schematics/update 0.1100.5
rxjs 6.6.0
typescript 4.0.2
形成
-
- バックエンド
-
- Express( http://localhost:3000 )
-
- フロンドエンド
- Angular( http://localhost:4200 )
后端
本節将实现一个简单的服务器,用于接收使用Express发出的请求。虽然本文的目的是通过Angular实现Http客户端,但为了实现这一目的,也需要一个与之配合的后端。关于Express的开发环境搭建,可以参考这篇文章(链接)。
var express = require('express');
var router = express.Router();
var strage = {
id: 0,
message: 'デフォルトメッセージ'
};
const strages = [strage];
/**
* HTTP の GET メソッドを待ち受けてステータスコードと文字列, メッセージリストを返す
* レスポンスは下記のJSONフォーマットで返却する
* {
* status: 200,
* response: 'メッセージリストを返却',
* messages: {{メッセージリスト}}
* }
* といった JSON が返却される
*/
router.get('/message/get', function(req, res, next) {
res.status(200);
res.json({
status: 200,
response: 'メッセージリストを返却',
messages: strages
});
});
module.exports = router;
关于实现没有特别的要点,就按照代码中的注释来做。
虽然重复了源代码的注释,但只是简单地在路由器上注册了一个等待接收 HTTP 的 GET 方法的处理程序。
{
status: 200,
response: 'メッセージリストを返却',
messages: {{メッセージリスト}}
}
回复如下。
前端
按照开头所述,这里我们使用Angular标准提供的Http HttpClient服务来实现HTTP客户端。
在以下的部分,我们将探讨如何实现向后端发出GET请求并显示从后端获取的字符串。
为了使用 HttpClient 服务,导入 HttpClientModule。
为了使用 Http HttpClient 服务,需要在 app.module.ts 中导入 HttpModule HttpClientModule。
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
// HTTP クライアントのための import ( 下記は Angular 5.0.0 で非推奨となった )
//import { HttpModule } from '@angular/http';
// HTTP クライアントのための import ( Angular 5.0.0 以降はこちらを使う )
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
// HTTP クライアントとしてのコンポーネント
import { HttpClientComponent } from './http-client/http-client.component';
// バックエンドとの通信を実際に担当するサービス
import { HttpClientService } from './service/http-client.service';
@NgModule({
declarations: [
AppComponent,
HttpClientComponent
],
imports: [
BrowserModule,
FormsModule,
// モジュールを利用を宣言する
// 下記は Angular 5.0.0 で非推奨となった
//HttpModule
// Angular 5.0.0 以降はこちらを使う
HttpClientModule
],
providers: [
// 自作サービスをアプリ全体で DI するために登録する
HttpClientService
],
bootstrap: [AppComponent]
})
export class AppModule { }
在app.module.ts中,您需要查看以下两个方面。
- 在中国人的日常生活中,只需要一种选择:“HttpModule HttpClientModule”的导入声明。
通过这两点来准备在整个应用程序中使用 Http 服务。
负责与后端通信的服务(例如GET请求)
实现一个负责与后端进行实际通信的服务的角色。实现内容大致如下:
Http HttpClient サービスの import
バックエンドから提供されている REST-API の実行
以下是GET请求的示例代码。
import { Injectable } from '@angular/core';
// REST クライアント実装ののためのサービスを import ( 下記は Angular 5.0.0 で非推奨となった )
//import { Http } from '@angular/http';
// REST クライアント実装ののためのサービスを import ( Angular 5.0.0 以降はこちらを使う )
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Injectable()
export class HttpClientService {
// 下記のコードは非推奨
/**
* リクエストヘッダを定義
*
* @private
* @memberof HttpClientService
*/
//private headers: any = new Headers({'Content-Type': 'application/json'});
// `Headers` の代わりに `HttpHeaders` を利用する
// またコメントにあるとおり、 `Authorization` を設定できるように `httpOptions` としてオブジェクトでラップしている
// 参考
// https://angular.jp/guide/http#%E3%83%98%E3%83%83%E3%83%80%E3%83%BC%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B
/**
* Http クライアントを実行する際のヘッダオプション
* @private
* @type {*}
* @memberof HttpClientService
* @description
* 認証トークンを使用するために `httpOptions` としてオブジェクトを用意した。
*/
private httpOptions: any = {
// ヘッダ情報
headers: new HttpHeaders({
'Content-Type': 'application/json'
}),
//
// レスポンスにヘッダ情報を入れるための設定
// https://angular.io/guide/http#reading-the-full-response
//
observe: 'response', // ⇐ これを追加
//
// DELETE 実行時に `body` が必要になるケースがあるのでプロパティとして用意しておく
// ( ここで用意しなくても追加できるけど... )
body: null
};
/**
* RST-API 実行時に指定する URL
*
* バックエンドは Express で実装し、ポート番号「3000」で待ち受けているため、
* そのまま指定すると CORS でエラーになる
* それを回避するため、ここではフロントエンドのポート番号「4200」を指定し、
* Angular CLI のリバースプロキシを利用してバックエンドとの通信を実現する
*
* @private
* @memberof HttpClientService
*/
private host: string = 'http://localhost:4200/app';
/**
* コンストラクタ. HttpClientService のインスタンスを生成する
*
* @param {Http} http Httpサービスを DI する
* @memberof HttpClientService
*/
constructor(private http: HttpClient) {
// `Authorization` に `Bearer トークン` をセットする
this.setAuthorization('my-auth-token');
}
/**
* HTTP GET メソッドを実行する
* (toPromise.then((res) =>{}) を利用する場合のコード)
*
* @returns {Promise<any[]>}
* @memberof HttpClientService
*/
public get(): Promise<any[]> {
return this.http.get(this.host + '/message/get', this.httpOptions)
.toPromise()
.then((res) => {
// response の型は any ではなく class で型を定義した方が良いが
// ここでは簡便さから any としておく
// @angular/http では json() でパースする必要があったが、 @angular/common/http では不要となった
//const response: any = res.json();
const response: any = res;
return response;
})
.catch(this.errorHandler);
}
/**
* REST-API 実行時のエラーハンドラ
* (toPromise.then((res) =>{}) を利用する場合のコード)
*
* @private
* @param {any} err エラー情報
* @memberof HttpClientService
*/
private errorHandler(err) {
console.log('Error occured.', err);
return Promise.reject(err.message || err);
}
/**
* Authorizatino に認証トークンを設定しする
*
* @param {string} token 認証トークン
* @returns {void}
* @memberof HttpClientService
* @description
* トークンを動的に設定できるようメソッド化している
* Bearer トークンをヘッダに設定したい場合はこのメソッドを利用する
*/
public setAuthorization(token: string = ''): void {
if (!token) {
return;
}
const bearerToken: string = `Bearer ${token}`;
this.httpOptions.headers = this.httpOptions.headers.set('Authorization', bearerToken);
}
}
关于代码附加说明要写。
-
- 在RST-API执行时指定的URL。
-
- 由于前端和后端的端口号不同,因此会出现由CORS引起的错误。
-
- 如下所述,在本文中我们使用Angular CLI的反向代理来避免这个问题,并在此处指定反向代理的URL为http://localhost:4200/app。
执行RESTR-API
通过执行Http HttpClient服务的get方法,执行后端提供的REST-API。
注意,此时使用箭头函数中的toPromise.then((res) => {})来接收响应。
这是一种通过toPromise()来异步接收执行REST-API,并在接收到响应后通过then((res) => {})进行处理的流程。
此外,通过toPromise()将本来是Observable对象的http.get()的返回值强制转换为Promise对象,从而使后续处理可以在Promise对象的方法中进行。
接下来是如何处理返回的响应。
由于后端以JSON格式返回响应,因此在这里使用json()将响应恢复为JSON格式。
在@angular/http中需要使用json()进行解析,但在@angular/common/http中则不需要,所以在这里直接设置返回的响应。
设置授权
为了能够动态设置Bearer令牌,我们将设置令牌的过程封装为setAuthorization()方法。
尽管本文在构造函数中执行这个方法,但不一定非要在构造函数中执行。可以在获得令牌的时候设置,或者在其他合适的时机设置。请根据需求选择合适的时机。
补充说明
尽管在注释中提到,对于从后端返回的数据,最好是准备一个类或接口来存储返回的值,而不是使用any进行处理。但在本文中,由于是示例代码,所以使用any来处理。
使用创建的服务的组件
使用已创建的 HttpClientService 实现一个从后端获取信息的组件。
import { Component, OnInit } from '@angular/core';
import { HttpClientService } from '../service/http-client.service';
@Component({
selector: 'app-http-client',
templateUrl: './http-client.component.html',
styleUrls: ['./http-client.component.css']
})
export class HttpClientComponent implements OnInit {
/**
* バックエンドから返却されたレスポンスをセットするプロパティ
*
* 型は any ではなく class で型を定義した方が良いが
* ここでは簡便さから any としておく
*
* @private
* @type {string}
* @memberof HttpClientComponent
*/
public param: any = {};
/**
* バックエンドから返却されたたメッセージをセットするプロパティ
*
* @type {*}
* @memberof HttpClientComponent
*/
public messageInfo: any = {
id: null,
message: null
};
/**
* バックエンドから返却されたたメッセージを保持するリストプロパティ
*
* @type {*}
* @memberof HttpClientComponent
*/
public messageInfoList: any = [this.messageInfo];
/**
* メッセージ登録回数
*
* @private
* @type {number}
* @memberof HttpClientComponent
*/
public messageId: number = 1;
/**
* 入力メッセージ
*
* @type {string}
* @memberof HttpClientComponent
*/
public message: string = '';
/**
* コンストラクタ. HttpClientComponent のインスタンスを生成する
* 自作した HttpClientService を DI する
*
* @param {HttpClientService} httpClientService HTTP通信を担当するサービス
* @memberof HttpClientComponent
*/
constructor(private httpClientService: HttpClientService) { }
/**
* ライフサイクルメソッド。コンポーネントの初期化で使用する
* 今回はコンポーネントの初期化時にバックエンドから情報を取得してビューに表示する
*
* @memberof HttpClientComponent
*/
ngOnInit() {
// ------
// toPromise.then((res) =>{}) を利用する場合のコード
// ------
this.httpClientService.get()
.then(
(response: any) => {
this.param = response.body;
this.messageInfoList = this.param.messages;
}
)
.catch(
(error) => console.log(error)
);
}
}
重点在于
ngOnInit() で HttpClientService の get() メソッドを実行している
在这些地方,它正在等待then()函数返回的处理结果并处理从后端返回的响应。
只需要一种选项:以下是返回的响应内容,response.body 中设置了后端返回的下一个 JSON 对象。
params = {
status: 200,
response: 'メッセージリストを返却',
messages: [
{
id: 0,
message: 'デフォルトメッセージ'
}
]
}
]
为了使用 *ngFor 在ビュー( http-client.html )上显示消息列表, 将返回的响应设置为 this.messageInfoList。
<!-- 片方向データバインドでバックエンドから取得した情報を表示する -->
<table class="table">
<caption>バックエンドから取得したメッセージリスト</caption>
<tr>
<th id="th-id">ID</th>
<th id="th-message">メッセージ</th>
</tr>
<!--インデックス番号(index)に変数iでアクセスできるように-->
<tr *ngFor="let messageInfo of messageInfoList; index as i">
<td>{{messageInfo.id}}</td>
<td>{{messageInfo.message}}</td>
</tr>
</table>
<form #formCheck="ngForm" class="formCheck">
<input type="text" id="form-id" class="input-text" name="message-id" [(ngModel)]="messageId">
<input type="text" id="form-message" class="input-text" name="message" [(ngModel)]="message">
</form>
<input type="button" id="register" value="登録" (click)="onClickRegister($event)">
<input type="button" id="update" value="更新" (click)="onClickUpdate($event)">
<input type="button" id="delete" value="削除" (click)="onClickDelete($event)">
为了显示消息列表,视图处理是使用*ngFor从先前设置的messageInfoList类中提取一个个元素,然后引用id和message属性。
なお、タグ以降のブロックは、メッセージの「登録」、「更新」、「削除」を行うためのインターフェースの一部分です。「登録」、「更新」、「削除」の処理については、後述の補足-2で実装例を説明していますので、参考にしてください。
使用Angular CLI进行反向代理设置
首先要重申的是,本次内容的结构如下:
-
- フロントエンドが Angular でポート番号:4200 で起動する
- バックエンドが Express でポート番号:3000 で起動する
在这种情况下,由于两者的端口号不同,所以即使从前端向后端发送请求,也会在CORS中出现错误。
为了避免这个问题,可以使用Angular CLI进行反向代理的设置。
(关于反向代理的设置,请参考这篇文章。仅供参考。)
以下为设定的内容。
- リバースプロキシ設定ファイル(proxy.conf.json)
{
// localhost:4200/app を localhost:3000 にフォワード
"/app": {
"target": "http://localhost:3000",
"pathRewrite": {"^/app": ""}
}
}
- リバースプロキシ有りで起動するためのスクリプト
// 省略
"scripts": {
// 省略
// リバースプロキシ設定ファイルを読み込ませて起動する
"start": "ng serve --proxy-config proxy.conf.json",
// 省略
},
// 省略
设定了反向代理后,前端和后端之间的连接将会如下图所示。
- リバースプロキシ後のフロントエンド⇔バックエンド間
フロントエンド ------> Angular CLI によるリバースプロキシ ------> バックエンド
(locahost:4200) (localhost:3000)
当重新检查前面提到的 HttpClientService 和后端的 GET 方法时,在这里。
- フロントエンド
// 省略
private host: string = 'http://localhost:4200/app';
// 省略
/**
* HTTP GET メソッドを実行する
* (toPromise.then((res) =>{}) を利用する場合のコード)
*
* @returns {Promise<any[]>}
* @memberof HttpClientService
*/
public get(): Promise<any[]> {
return this.http.get(this.host + '/message/get', this.httpOptions)
.toPromise()
.then((res) => {
// response の型は any ではなく class で型を定義した方が良いが
// ここでは簡便さから any としておく
const response: any = res;
return response;
})
.catch(this.errorHandler);
}
- バックエンド
/**
* HTTP の GET メソッドを待ち受けてステータスコードと文字列, メッセージリストを返す
* レスポンスは下記のJSONフォーマットで返却する
* {
* status: 200,
* response: 'メッセージリストを返却',
* messages: {{メッセージリスト}}
* }
* といった JSON が返却される
*/
router.get('/message/get', function(req, res, next) {
res.status(200);
res.json({
status: 200,
response: 'メッセージリストを返却',
messages: strages
});
});
已经实施。
总结前述内容,包括反向代理的设置、前端实现和后端实现所意图的内容,则可以如下表达:
将之前提到的反向代理的设置、前端实现和后端实现的目标进行综述,可简洁概括如下:
-
- 反向代理的设置将 localhost:4200/app 转发到 localhost:3000
-
- 后端在 localhost:3000/get 上等待请求
-
- 前端在 localhost:4200/app/get 上发出请求
-
- 通过反向代理的设置,上述请求被转发到 localhost:3000/get
- 后端能够成功接收请求
成为如此。
当以前的参考文章中所提到的,当使用反向代理启动Angular时,请确保已设置好反向代理。
$ npm start
需要注意的是,虽然使用ng serve命令可以启动应用程序,但是由于存在反向代理,应用程序并未正确启动,因此无法按预期工作。
运行结果
请使用以下命令启动后端和前端。
$ npm start
$ npm start
一起启动后,从浏览器中查看执行结果。
我确认看到了从后端返回的值,即“默认消息”被显示出来。
填充-1
在这篇文章中提到了使用 HttpClientService 的 get() 方法并示范了使用 toPromise.then() 的例子,但也可以选择使用 subscribe() 作为替代方法。
在这种情况下,相应的每个代码将被实现如下。
将toPromise().then()替换为subscribe()。
- サービス
/**
* HTTP GET メソッドを実行する
* (subscribe((res) =>{}) を利用する場合のコード)
*
* @param {*} callback HTTP GET の実行結果を受け取って処理するためのコールバック処理
* @memberof HttpClientService
*/
public get(callback: any) {
this.http.get(this.host + '/message/get', this.httpOptions)
.subscribe(
(res) => {
const response: any = res;
callback(response);
},
(error) => {
// subscribe の実装のときに this.errorHandler でエラー処理を
// 行うと Uncaught (in promise) が発生するので、
// ここではコンソールにログを出すだけにする
console.log(error);
}
);
}
- コンポーネント
/**
* ライフサイクルメソッド。コンポーネントの初期化で使用する
* 今回はコンポーネントの初期化時にバックエンドから情報を取得してビューに表示する
*
* @memberof HttpClientComponent
*/
ngOnInit() {
// ------
// subscribe((res) =>{}) を利用する場合のコード
// ------
// HTTP GET の実行結果を受け取るためのコールバックを引数に、 get() を呼び出す
this.httpClientService.get((response: any) => {
this.param = response.body;
this.messageInfoList = this.param.messages;
});
}
填補-2
以下是POST、PUT和DELETE的示例。这些示例涉及对存储在内存中的消息信息的处理,但仅供您了解处理方式。
虽然在后端可能会返回错误,但前端只需将该错误输出为日志,使用 console.log(error),不进行其他处理。
邮寄
后端
/**
* HTTP の POST メソッドを待ち受けてメッセージを登録する
* 成功時、ステータスコードと文字列、登録後のメッセージリストを返す
*
* レスポンスは下記のJSONフォーマットで返却する
* {
* status: 200,
* response: 'メッセージを登録',
* messages: {{メッセージリスト}}
* }
* といった JSON が返却される
*/
router.post('/message/post', function(req, res, next) {
if (!req.body.id || req.body.id === '') {
res.status(400);
res.json({status: 400, response: 'IDが指定されていない'})
return;
}
for (var i = 0; i < strages.length; i++) {
if (req.body.id === strages[i].id) {
res.status(409);
res.json({
status: 409,
response: 'IDが重複',
messages: req.body
})
return;
}
}
const localStorage = {
id: req.body.id,
message: req.body.message
};
strages.push(localStorage);
res.status(200);
res.json({
status: 200,
response: 'メッセージを登録',
messages: strages
})
});
前端
- サービス
/**
* メッセージ登録
*
* @param {*} body リクエストボディ
* @returns {Promise<any[]>} バックエンドからのレスポンス
* @memberof HttpClientService
*/
public register(body: any): Promise<any[]> {
return this.http.post(this.host + '/message/post', body, this.httpOptions)
.toPromise()
.then((res) => {
const response: any = res;
return response;
})
.catch(this.errorHandler);
}
- コンポーネント
/**
* メッセージ登録
*
* @private
* @memberof HttpClientComponent
*/
private doRegister() {
const body: any = {
id: this.messageId,
message: this.message
};
this.httpClientService.register(body)
.then(
(response: any) => {
this.param = response.body;
this.messageInfoList = this.param.messages;
}
)
.catch(
(error) => console.log(error)
);
}
把东西放置
后端
/**
* HTTP の PUT メソッドを待ち受けてメッセージを更新する
* 成功時、ステータスコードと文字列、 更新後のメッセージリストを返す
*
* レスポンスは下記のJSONフォーマットで返却する
* {
* status: 200,
* response: 'メッセージを更新',
* messages: {{メッセージリスト}}
* }
* といった JSON が返却される
*/
router.put('/message/put', function(req, res, next) {
if (!req.body.id || req.body.id === '') {
res.status(400);
res.json({
status: 400,
response: 'IDが指定されていない',
message: req.body
})
return;
}
for (var i = 0; i < strages.length; i++) {
if (req.body.id === strages[i].id) {
strages[i].message = req.body.message;
res.status(200);
res.json({
status: 200,
response: 'メッセージを更新',
messages: strages
})
return;
}
}
res.status(404);
res.json({
status: 404,
response: '対象のメッセージが存在しない',
messages: req.body
})
});
前端
- サービス
/**
* メッセージ更新
*
* @param {*} body リクエストボディ
* @returns {Promise<any[]>} バックエンドからのレスポンス
* @memberof HttpClientService
*/
public update(body: any): Promise<any[]> {
return this.http.put(this.host + '/message/put', body, this.httpOptions)
.toPromise()
.then((res) => {
const response: any = res;
return response;
})
.catch(this.errorHandler);
}
- コンポーネント
/**
* メッセージ更新
*
* @private
* @memberof HttpClientComponent
*/
private doUpdate() {
const body: any = {
id: this.messageId,
message: this.message
};
this.httpClientService.update(body)
.then(
(response: any) => {
this.param = response.body;
this.messageInfoList = this.param.messages;
}
)
.catch(
(error) => console.log(error)
);
}
删除
后端 (Chinese translation for “backend”)
/**
* HTTP の DELETE メソッドを待ち受けてメッセージを削除する
* 成功時、ステータスコードと文字列、 削除後のメッセージリストを返す
*
* レスポンスは下記のJSONフォーマットで返却する
* {
* status: 200,
* response: 'メッセージを削除',
* messages: {{メッセージリスト}}
* }
* といった JSON が返却される
*/
router.delete('/message/delete', function(req, res, next) {
if (!req.body.id || req.body.id === '') {
res.status(400);
res.json({
status: 400,
response: 'IDが指定されていない',
message: req.body
})
return;
}
for (var i = 0; i < strages.length; i++) {
if (req.body.id === strages[i].id) {
strages.splice(i, 1);
res.status(200);
res.json({
status: 200,
response: 'メッセージを削除',
messages: strages
})
return;
}
}
res.status(404);
res.json({
status: 404,
response: '対象のメッセージが存在しない',
messages: req.body
})
});
前端
DELETE については次の点に注意
Http サービスの delete メソッドでは body を引数にセットできない
DELETE 時に body をセットしたい場合、例に示したように Header Option に含める 必要がある
サービス
/**
* メッセージ削除
*
* @param {*} body リクエストボディ
* @returns {Promise<any[]>} バックエンドからのレスポンス
* @memberof HttpClientService
*/
public delete(body: any): Promise<any[]> {
this.httpOptions.body = body;
return this.http.delete(this.host + '/message/delete', this.httpOptions)
.toPromise()
.then((res) => {
const response: any = res;
return response;
})
.catch(this.errorHandler);
}
- コンポーネント
/**
* メッセージ削除
*
* @private
* @memberof HttpClientComponent
*/
private doDelete() {
const body: any = {
id: this.messageId
};
this.httpClientService.delete(body)
.then(
(response: any) => {
this.param = response.body;
this.messageInfoList = this.param.messages;
}
)
.catch(
(error) => console.log(error)
);
}
执行 POST、PUT、DELETE 的结果.
邮递
放置
删除
3个补充
要在响应中包含头信息,应该怎么做?
在执行HttpClient的每个方法时,添加 observe: ‘response’ 作为选项。
就本文的代码来说,下面的部分就是。
private httpOptions: any = {
// ヘッダ情報
headers: new HttpHeaders({
'Content-Type': 'application/json'
}),
//
// レスポンスにヘッダ情報を入れるための設定
// https://angular.io/guide/http#reading-the-full-response
//
observe: 'response', // ⇐ これを追加
//
// DELETE 実行時に `body` が必要になるケースがあるのでプロパティとして用意しておく
// ( ここで用意しなくても追加できるけど... )
body: null
};
设定如上时,响应内容为什么?
获取响应
[get] response:
{
"headers":{
"normalizedNames":{},
"lazyUpdate":null
},
"status":200,
"statusText":"OK",
"url":"http://localhost:4200/app/get",
"ok":true,
"type":4,
"body":{
"status":200,
"response":"メッセージリストを返却",
"messages":[
{
"id":0,
"message":"デフォルトメッセージ"
}
]
}
}
讨论帖的回复
[post] response: {
"headers":{
"normalizedNames":{},
"lazyUpdate":null
},
"status":200,
"statusText":"OK",
"url":"http://localhost:4200/app/post",
"ok":true,
"type":4,
"body":{
"status":200,
"response":"メッセージを登録",
"messages":[
{
"id":0,
"message":"デフォルトメッセージ"
},
{
"id":1,
"message":"hogehoge"
}
]
}
}
将”put”的响应解释。
[put] response: {
"headers":{
"normalizedNames":{},
"lazyUpdate":null
},
"status":200,
"statusText":"OK",
"url":"http://localhost:4200/app/put",
"ok":true,
"type":4,
"body":{
"status":200,
"response":"メッセージを更新",
"messages":[
{
"id":0,
"message":"デフォルトメッセージ"
},
{
"id":1,
"message":"hogehogehogehoge"
}
]
}
}
删除响应
[delete] response: {
"headers":{
"normalizedNames":{},
"lazyUpdate":null
},
"status":200,
"statusText":"OK",
"url":"http://localhost:4200/app/delete",
"ok":true,
"type":4,
"body":{
"status":200,
"response":"メッセージを削除",
"messages":[
{
"id":0,"message":"デフォルトメッセージ"
}
]
}
}
源代码
請參考以下連結,其中包含了本次文章所使用的程式碼進行的操作驗證。
-
- フロントエンド
- バックエンド
请参考
-
- Version 5.0.0 of Angular Now Available
-
- Angular 5.0.0がリリースされました( 上記の日本語訳 )
-
- HttpClient – 公式の日本語ドキュメント
- Communicating with backend services using HTTP > Reading the full response