HTTP服务
HTTP服务是Angular中使用HTTP协议与远程服务器进行通讯的一个独立模块,要使用它需要三个步骤
- 在根模块中导入HttpModule,我们通过
Http
客户端,使用熟悉的 HTTP 请求/回应协议与服务器通讯。Http
客户端是Angular的HTTP库所提供的一系列服务之一。
import { HttpModule } from '@angular/http';
...
@NgModule({
imports:[
...
HttpModule
],
...
- 在组件模块中导入HTTP服务
import { Http } from '@angular/http';
- 在组件构造函数中声明引入
constructor(private http: Http){
...
}
引入HTTP服务后,组件就可以用AJAX和JSONP两种方式发送数据请求了。先大概讲解一下Http服务类,它可以做下面这些事,get、post、put... (RequestOptionsArgs是HTTP请求参数)
class Http {
constructor(_backend: ConnectionBackend, _defaultOptions: RequestOptions)
request(url: string|Request, options?: RequestOptionsArgs) : Observable<Response>
get (url: string, options?: RequestOptionsArgs) : Observable<Response>
post (url: string, body: any, options?: RequestOptionsArgs) : Observable<Response>
put (url: string, body: any, options?: RequestOptionsArgs) : Observable<Response>
delete (url: string, options?: RequestOptionsArgs) : Observable<Response>
patch (url: string, body: any, options?: RequestOptionsArgs) : Observable<Response>
head (url: string, options?: RequestOptionsArgs) : Observable<Response>
options(url: string, options?: RequestOptionsArgs) : Observable<Response>
}
AJAX
AJAX是使用XMLHttpRequest对象向服务器发送请求并处理响应的通讯技术。XMLHttpRequest支持同步和异步的方式发送请求,但一般只用异步方式。
处理异步操作的方式有几种,Angular推荐使用Observable,它的HTTP服务的API接口返回的也是Observable对象。Observable是响应式编程模型Rx的核心概念,RxJS是它的JavaScript版本。注意RxJS的Observable实现的是"冷"模式,只有被订阅后才会发送请求。记得导入rxjs的操作符
一般我们将数据服务单独创建为一个服务类,需要引入
import { Injectable } from '@angular/core';
import { Http, RequestOptions, Headers } from '@angular/http';
import 'rxjs/add/operator/map'; //根据需要导入合适的操作符
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
一般也就用get和post,
const DATES_URL = '访问路径';
@Injectable()
export class ContactService {
constructor(private http: Http) {}
getDates():Observable<Response> {
return this.http.get(DATES_URL) //get数据
.map(response=>response.json().data) //通过map操作来对response进行预先处理,转成JSON对象
.catch(this.handleError); //异常处理
}
postDates(date: any): Observable<Response> {
let body = JSON.stringify(date);
let headers = new Headers({'Content-Type':'application/json'});
let options = new RequestOptions({headers: headers});
return this.http.post(DATES_URL,body,options)
.map(response=>response.json().data)
.catch(this.handleError);
}
private handleError(error: any) {
console.error('An error occurred', error);
return Observable.throw(error.message || error);
}
创建好服务后,就可以在别的组件用它了
import { ContactService } from '刚才的服务类路径';
@Component({
...
})
export class ... {
constructor(private contactService: ContactService) {}
...
getDate() {
return this.contactService.getDate()
.subscribe(
date => this.date = date,
error => this.erroMessage = <any>error);
}
postDate(date: any) {
if (!any) {return;)
this.contactService.postDate()
.subscribe(
date => this.date.push(date),
error => this.erroMessage = <any>error);
}
}
JSONP
JSONP用于向当前页面不同源的服务器发起AJAX请求,因为<script>标签请求资源不会受到同源策略限制,JSONP就是利用<script>标签来发起GET请求,在这个GET请求中传递callback参数给服务器,然后服务端返回一段JavaScript代码,一般以callback函数包裹着JSON数据的形式返回。注意的是JSONP只能发起GET请求。
根模块加载JsonpModule,然后就可以在服务类中运用了。首先在构造函数中注入JSONP服务,然后使用URLSearchParams对象构造请求参数,最后调用JSONP服务的get()方法发起请求。
import { Injectable } from '@angular/core';
import { Jsonp, URLSearchParams } from '@angular/http';
import 'rxjs/add/operator/map';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
@Injectable()
export class DatesService {
constructor(private jsonp: Jsonp) {}
getDates() {
let URL = '访问路径';
let params = new URLSearchParams();
params.set('foramt','json');
params.set('callback','JSONP_CALLBACK');
return this.jsonp
.get(URL,{search: params})
.map(response => response.json().date)
.subscribe(
dates => this.dates = dates,
error => this.erroMsg = <any>error)
}
}
最后说明几点
响应数据是JSON字符串格式的,我们必须把这个字符串解析成 JavaScript 对象,只要调一下response.json()就可以了。
解码后的 JSON 不是我们直接想要的结果, 调用的这个服务器总会把 JSON 结果包装进一个带data
属性的对象中。response.json().data才是我们要的