ionic3-handbook
ionic3-handbook copied to clipboard
10、网络请求
大多数App不是简单的只使用本地数据,通常还会与服务器进行交互,这个时候就要用到网络请求的功能了。ionic的网络请求其实就是用的是Angular的。下面就结合豆瓣API的例子,对这个功能讲解下,然后根据实际项目的规范对其进行封装。
在根目录下,使用ionic generate page net
创建一个新界面。然后在主页添加按钮,跳转到此界面。相关代码如下:
home.html
...
<button class="btn-primary" (click)="toNetPage()">跳转到网络请求界面</button>
horm.ts
...
toNetPage(){
this.navCtrl.push('NetPage');
}
网络请求的功能在单独的模块中,我们需要先在AppModule中导入,代码如下:
app.modules.ts
import { HttpClientModule } from '@angular/common/http';
imports: [
HttpClientModule,
...
]
紧接着我们才使用,具体代码见net.ts:
net.ts
import {HttpClient,HttpHeaders} from '@angular/common/http';
import 'rxjs/add/operator/timeout';
...
export class NetPage {
constructor(private http : HttpClient) {}
ionViewDidLoad() {
this.http.get('https://api.douban.com/v2/movie/in_theaters?start=0&count=1')
.timeout(10000) // 10秒无反应则报错
.subscribe(success => {
console.log(success);
}, fail => {
console.log('请求失败');
});
}
}
通过ionic serve
命令运行项目,在首页点击进入网络请求页,在Console
中你会发现如下图所示的错误。
有经验的人一下子就看出是跨域问题,跨域问题的解决方案很多,这里就不一一提及,典型的就是使用代理,我这儿为了方便是关闭Chrome浏览器的安全策略,从而使其支持跨域请求,Mac OS上关闭安全策略的命令如下:
open -n /Applications/Google\ Chrome.app/ --args --disable-web-security --user-data-dir=/Users/你的自己的用户名/MyChromeDevUserData/
在终端中运行会新出现一个Chrome浏览器,输入localhost:8100访问我们的已经运行的项目,从首页进入网络请求页,返回的数据如图所示。

封装
通常我们的网络请求有自己的请求头等东西,每个网络请求的界面都写一次太麻烦了,所以自然而然就想到了对网络请求进行封装,这儿provider
就该上场了。
在项目根目录下运行ionic generate provider http
,最后的目录结构如下:
── app
├── assets
├── components
├── index.html
├── manifest.json
├── pages
├── providers
│ └── http
│ └── http.ts
除此之外,还会在app.module.ts中自动添加如下代码:
app.modules.ts
import { HttpProvider } from '../providers/http/http';
providers: [
HttpProvider
]
之前提到过provider
其实就是Angular
中的service
,只是换了个名字,它的用法涉及到依赖注入的概念,代码中会有@Injectable()
这个装饰器,更多的内容需要大家自己去学习。这里只强调一点,创建一个provider
文件,都要在app.module.ts
的providers
中引入,不然会报错。
接着将我们网络请求的代码写在里面,如下:
http.ts
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/timeout';
@Injectable()
export class HttpProvider {
constructor(public http : HttpClient) {}
// get请求
get(url) {
return this.http.get(url).timeout(10000).catch(this.handlerError);
}
// post请求,request是请求参数组成的Object
post(url, request) {
const body : string = JSON.stringify(request);
const httpOptions = {
headers: new HttpHeaders({'Content-Type': 'application/json'})
};
return this.http.post(url, body, httpOptions).timeout(10000).catch(this.handlerError);
}
private handlerError(error : Response | any) {
const body = error.json() || {};
return Observable.throw(body);
}
}
用法如下:
net.ts
...
import {HttpProvider} from '../../providers/http/http';
export class NetPage {
constructor(private http : HttpProvider) {}
ionViewDidLoad() {
this.http.get('https://api.douban.com/v2/movie/in_theaters?start=0&count=5')
.subscribe(success => {
console.log(success)
}, fail => {
console.log('网络错误');
});
}
}
我在项目代码里还写了个post请求的例子,大家可以查看下。
感谢您的教程!非常简洁明了~
@farashraid 惭愧啦,之前写的,里面还有很多不足,需要更正的。