现代移动应用几乎都需要与服务器进行交互,无论是向 REST API 发送 POST 请求,还是从远程服务器加载静态资源。React Native 提供了丰富的 API 来满足这些网络需求。
一、 核心工具:Fetch API
React Native 内置了 Fetch API ,这是处理网络请求的首选方式。如果你曾在 Web 前端开发中使用过 fetch 或 XMLHttpRequest,你会发现它非常熟悉。
1. 发起请求 (Making requests)
最简单的 GET 请求:
要从任意 URL 获取内容,只需将 URL 传递给 fetch:
TypeScript
fetch('https://mywebsite.com/mydata.json');
自定义请求 (POST, Headers):
fetch 接受可选的第二个参数,用于定制 HTTP 请求。你可以指定额外的 Headers 或将请求方法改为 POST:
TypeScript
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
}),
});
2. 处理响应 (Handling the response)
网络请求本质上是异步 的。Fetch 方法会返回一个 Promise,这使得异步代码的编写变得非常直观。
方式一:使用 Promise 链 (.then)
TypeScript
const getMoviesFromApi = () => {
return fetch('https://reactnative.dev/movies.json')
.then(response => response.json()) // 将响应解析为 JSON
.then(json => {
return json.movies;
})
.catch(error => {
console.error(error); // 别忘了捕获错误!
});
};
方式二:使用 Async / Await (推荐)
这种语法让异步代码看起来更像同步代码,逻辑更清晰:
TypeScript
const getMoviesFromApiAsync = async () => {
try {
const response = await fetch('https://reactnative.dev/movies.json');
const json = await response.json();
return json.movies;
} catch (error) {
console.error(error); // 如果不捕获,错误会被静默丢弃
}
};
二、 安全限制:HTTP vs HTTPS
在移动端开发中,网络安全性受到了严格的限制,如果你试图请求非加密的 http:// 链接,可能会遭遇失败。
1. iOS: App Transport Security (ATS)
iOS 9.0 及以上版本默认开启 ATS,强制要求所有 HTTP 连接使用 HTTPS。
- 解决办法: 如果你需要请求明文 URL(http 开头),你必须在
Info.plist文件中添加 ATS 异常配置。 - 注意: 苹果 App Store 审核要求对禁用 ATS 提供合理的理由。如果可能,尽量只针对特定域名开启例外,而不是完全禁用 ATS。
2. Android: Cleartext Traffic
从 Android API Level 28 (Android 9) 开始,明文流量(Cleartext traffic)默认也被阻止。
- 解决办法: 如果必须使用 http,需在
AndroidManifest.xml中设置android:usesCleartextTraffic="true"。
三、 第三方库与 XMLHttpRequest
React Native 内置了 XMLHttpRequest API。这意味着:
- 你可以直接使用
XMLHttpRequest对象编写原生风格的请求代码。 - 更重要的是: 你可以使用依赖于此 API 的第三方流行库,例如 Axios 或 Frisbee。
TypeScript
// 原生 XMLHttpRequest 示例
const request = new XMLHttpRequest();
request.onreadystatechange = e => {
if (request.readyState !== 4) return;
if (request.status === 200) {
console.log('success', request.responseText);
} else {
console.warn('error');
}
};
request.open('GET', 'https://mywebsite.com/endpoint/');
request.send();
⚠️ 警告:
原生应用中没有浏览器的 CORS (跨域资源共享) 概念。因此,你在 Web 开发中遇到的跨域问题在 React Native 中通常不存在。
四、 实时通信:WebSocket
React Native 支持 WebSocket 协议,允许通过单个 TCP 连接进行全双工通信,非常适合聊天应用或实时数据推送。
TypeScript
const ws = new WebSocket('ws://host.com/path');
ws.onopen = () => {
// 连接已打开
ws.send('something');
};
ws.onmessage = e => {
// 收到消息
console.log(e.data);
};
ws.onerror = e => {
// 发生错误
console.log(e.message);
};
ws.onclose = e => {
// 连接关闭
console.log(e.code, e.reason);
};
五、 已知问题与坑 (Known Issues)
在使用 fetch 时,有一些已知的局限性需要注意:
-
不受支持的选项:
redirect: manual和credentials: omit目前在 React Native 中不生效。 -
Android Header 问题: 如果存在同名的 Header,Android 端只会保留最后一个。
-
Cookie 认证不稳定:
- 基于 Cookie 的认证目前不够稳定。
- 在 iOS 上,如果服务器返回
302重定向并且包含Set-Cookie,Cookie 可能无法正确设置。由于无法手动处理重定向,这可能导致会话过期时的无限重定向循环。
六、 进阶:iOS NSURLSession 配置
对于某些高级应用,你可能需要自定义 iOS 底层的 NSURLSession(例如设置全局 User Agent 或配置临时会话)。React Native 提供了 RCTSetCustomNSURLSessionConfigurationProvider 来实现这一点。
这需要编写原生 Objective-C 代码,通常在 AppDelegate.m 的 didFinishLaunchingWithOptions 方法中调用:
Objective-C
#import <React/RCTHTTPRequestHandler.h>
-(void)application:(__unused UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 设置自定义 NSURLSession 配置
RCTSetCustomNSURLSessionConfigurationProvider(^NSURLSessionConfiguration *{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
// 在这里配置 session,例如设置 HTTPAdditionalHeaders
return configuration;
});
// ... 启动 React Native
}