NativeScript 网络请求 #
网络请求概述 #
NativeScript 提供了多种方式进行网络请求,包括内置的 Http 模块和第三方库。
text
┌─────────────────────────────────────────────────────────────┐
│ 网络请求方式 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 内置模块 │
│ ├── @nativescript/core/http 基础 HTTP 请求 │
│ └── fetch API 标准 Fetch 接口 │
│ │
│ 第三方库 │
│ ├── axios 流行的 HTTP 客户端 │
│ └── Angular HttpClient Angular HTTP 模块 │
│ │
└─────────────────────────────────────────────────────────────┘
使用 Http 模块 #
基本请求 #
typescript
import { Http } from '@nativescript/core';
// GET 请求
const response = await Http.getJSON<ApiResponse>('https://api.example.com/users');
console.log(response);
// POST 请求
const response = await Http.request({
url: 'https://api.example.com/users',
method: 'POST',
headers: { 'Content-Type': 'application/json' },
content: JSON.stringify({
name: 'John',
email: 'john@example.com'
})
});
console.log(response.content.toJSON());
GET 请求 #
typescript
// 简单 GET
const data = await Http.getJSON<User[]>('https://api.example.com/users');
// 带参数 GET
const url = 'https://api.example.com/users?page=1&limit=10';
const data = await Http.getJSON<User[]>(url);
// 带请求头
const response = await Http.request({
url: 'https://api.example.com/users',
method: 'GET',
headers: {
'Authorization': 'Bearer token',
'Accept': 'application/json'
}
});
const data = response.content.toJSON();
POST 请求 #
typescript
// JSON 数据
const response = await Http.request({
url: 'https://api.example.com/users',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token'
},
content: JSON.stringify({
name: 'John',
email: 'john@example.com'
})
});
// 表单数据
const response = await Http.request({
url: 'https://api.example.com/upload',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
content: 'name=John&email=john@example.com'
});
PUT 请求 #
typescript
const response = await Http.request({
url: 'https://api.example.com/users/1',
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token'
},
content: JSON.stringify({
name: 'John Updated',
email: 'john.updated@example.com'
})
});
DELETE 请求 #
typescript
const response = await Http.request({
url: 'https://api.example.com/users/1',
method: 'DELETE',
headers: {
'Authorization': 'Bearer token'
}
});
文件上传 #
typescript
import { knownFolders, path } from '@nativescript/core';
const file = knownFolders.documents().getFile('image.jpg');
const response = await Http.request({
url: 'https://api.example.com/upload',
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data'
},
content: file
});
使用 Fetch API #
基本用法 #
typescript
// GET 请求
const response = await fetch('https://api.example.com/users');
const data = await response.json();
// POST 请求
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token'
},
body: JSON.stringify({
name: 'John',
email: 'john@example.com'
})
});
const data = await response.json();
封装 Fetch #
typescript
// services/api.service.ts
export class ApiService {
private baseUrl = 'https://api.example.com';
private token: string;
setToken(token: string) {
this.token = token;
}
private async request<T>(
endpoint: string,
options: RequestInit = {}
): Promise<T> {
const url = `${this.baseUrl}${endpoint}`;
const headers = {
'Content-Type': 'application/json',
...options.headers
};
if (this.token) {
headers['Authorization'] = `Bearer ${this.token}`;
}
const response = await fetch(url, {
...options,
headers
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
}
get<T>(endpoint: string): Promise<T> {
return this.request<T>(endpoint);
}
post<T>(endpoint: string, data: any): Promise<T> {
return this.request<T>(endpoint, {
method: 'POST',
body: JSON.stringify(data)
});
}
put<T>(endpoint: string, data: any): Promise<T> {
return this.request<T>(endpoint, {
method: 'PUT',
body: JSON.stringify(data)
});
}
delete<T>(endpoint: string): Promise<T> {
return this.request<T>(endpoint, {
method: 'DELETE'
});
}
}
使用 Axios #
安装 Axios #
bash
npm install axios
基本用法 #
typescript
import axios from 'axios';
// GET 请求
const response = await axios.get<User[]>('https://api.example.com/users');
console.log(response.data);
// POST 请求
const response = await axios.post<User>('https://api.example.com/users', {
name: 'John',
email: 'john@example.com'
});
// 带参数
const response = await axios.get<User[]>('https://api.example.com/users', {
params: {
page: 1,
limit: 10
}
});
创建实例 #
typescript
import axios, { AxiosInstance } from 'axios';
const api: AxiosInstance = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
headers: {
'Content-Type': 'application/json'
}
});
// 使用实例
const response = await api.get<User[]>('/users');
请求拦截器 #
typescript
// 请求拦截器
api.interceptors.request.use(
(config) => {
const token = getToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// 响应拦截器
api.interceptors.response.use(
(response) => {
return response.data;
},
(error) => {
if (error.response?.status === 401) {
// Token 过期,跳转登录
logout();
}
return Promise.reject(error);
}
);
Angular HttpClient #
配置 HttpClient #
typescript
// app.module.ts
import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [
NativeScriptModule,
HttpClientModule
]
})
export class AppModule {}
创建服务 #
typescript
// services/user.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class UserService {
private apiUrl = 'https://api.example.com';
constructor(private http: HttpClient) {}
getUsers(page: number = 1, limit: number = 10): Observable<User[]> {
const params = new HttpParams()
.set('page', page.toString())
.set('limit', limit.toString());
return this.http.get<ApiResponse<User[]>>(`${this.apiUrl}/users`, { params })
.pipe(
map(response => response.data),
catchError(this.handleError)
);
}
getUser(id: number): Observable<User> {
return this.http.get<User>(`${this.apiUrl}/users/${id}`);
}
createUser(user: CreateUserDto): Observable<User> {
return this.http.post<User>(`${this.apiUrl}/users`, user);
}
updateUser(id: number, user: UpdateUserDto): Observable<User> {
return this.http.put<User>(`${this.apiUrl}/users/${id}`, user);
}
deleteUser(id: number): Observable<void> {
return this.http.delete<void>(`${this.apiUrl}/users/${id}`);
}
private handleError(error: any): Observable<never> {
console.error('API Error:', error);
throw error;
}
}
使用拦截器 #
typescript
// interceptors/auth.interceptor.ts
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
const token = getToken();
if (token) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
}
return next.handle(request);
}
}
typescript
// app.module.ts
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from './interceptors/auth.interceptor';
@NgModule({
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
}
]
})
export class AppModule {}
错误处理 #
统一错误处理 #
typescript
// services/error-handler.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ErrorHandlerService {
handle(error: any): void {
let message = 'An error occurred';
if (error.status) {
switch (error.status) {
case 400:
message = 'Bad request';
break;
case 401:
message = 'Unauthorized';
this.handleUnauthorized();
break;
case 403:
message = 'Forbidden';
break;
case 404:
message = 'Not found';
break;
case 500:
message = 'Server error';
break;
default:
message = `Error: ${error.status}`;
}
} else if (error.message) {
message = error.message;
}
this.showError(message);
}
private handleUnauthorized(): void {
// 清除 token,跳转登录
}
private showError(message: string): void {
// 显示错误提示
console.error(message);
}
}
重试机制 #
typescript
import { retry, retryWhen, delay, scan } from 'rxjs/operators';
// 简单重试
this.http.get<User[]>('/users')
.pipe(
retry(3)
);
// 自定义重试
this.http.get<User[]>('/users')
.pipe(
retryWhen(errors =>
errors.pipe(
scan((count, error) => {
if (count >= 3) {
throw error;
}
return count + 1;
}, 0),
delay(1000)
)
)
);
网络状态检测 #
检测网络连接 #
typescript
import { ConnectionType, connectivity } from '@nativescript/core';
// 获取当前连接类型
const connectionType = connectivity.getConnectionType();
switch (connectionType) {
case ConnectionType.wifi:
console.log('WiFi connected');
break;
case ConnectionType.mobile:
console.log('Mobile network connected');
break;
case ConnectionType.none:
console.log('No network connection');
break;
}
// 监听网络变化
connectivity.startMonitoring((newConnectionType: number) => {
switch (newConnectionType) {
case ConnectionType.wifi:
console.log('WiFi connected');
break;
case ConnectionType.mobile:
console.log('Mobile network connected');
break;
case ConnectionType.none:
console.log('No network connection');
break;
}
});
// 停止监听
connectivity.stopMonitoring();
离线处理 #
typescript
// services/offline.service.ts
import { Injectable } from '@angular/core';
import { ConnectionType, connectivity } from '@nativescript/core';
@Injectable({
providedIn: 'root'
})
export class OfflineService {
private isOnline: boolean;
constructor() {
this.isOnline = connectivity.getConnectionType() !== ConnectionType.none;
connectivity.startMonitoring((type) => {
this.isOnline = type !== ConnectionType.none;
});
}
get online(): boolean {
return this.isOnline;
}
async requestWithOffline<T>(
onlineRequest: () => Promise<T>,
offlineFallback?: () => Promise<T>
): Promise<T> {
if (this.isOnline) {
return onlineRequest();
} else if (offlineFallback) {
return offlineFallback();
} else {
throw new Error('No network connection');
}
}
}
最佳实践 #
API 服务封装 #
typescript
// services/api.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
interface ApiResponse<T> {
data: T;
message: string;
status: number;
}
@Injectable({
providedIn: 'root'
})
export class ApiService {
private baseUrl = 'https://api.example.com/api/v1';
constructor(private http: HttpClient) {}
get<T>(endpoint: string, params?: any): Observable<T> {
return this.http.get<ApiResponse<T>>(`${this.baseUrl}${endpoint}`, { params })
.pipe(
map(response => response.data)
);
}
post<T>(endpoint: string, body?: any): Observable<T> {
return this.http.post<ApiResponse<T>>(`${this.baseUrl}${endpoint}`, body)
.pipe(
map(response => response.data)
);
}
put<T>(endpoint: string, body?: any): Observable<T> {
return this.http.put<ApiResponse<T>>(`${this.baseUrl}${endpoint}`, body)
.pipe(
map(response => response.data)
);
}
delete<T>(endpoint: string): Observable<T> {
return this.http.delete<ApiResponse<T>>(`${this.baseUrl}${endpoint}`)
.pipe(
map(response => response.data)
);
}
}
请求取消 #
typescript
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({
// ...
})
export class UserComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>();
constructor(private userService: UserService) {}
ngOnInit() {
this.userService.getUsers()
.pipe(
takeUntil(this.destroy$)
)
.subscribe(users => {
// 处理数据
});
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}
下一步 #
现在你已经掌握了网络请求,接下来学习 本地存储,了解如何存储本地数据!
最后更新:2026-03-29