跳到主要内容
版本:0.82

网络

许多移动应用需要从远程 URL 加载资源。你可能希望向 REST API 发起 POST 请求,或者从另一台服务器获取一段静态内容。

使用 Fetch

React Native 为你的网络需求提供了 Fetch API。如果你之前使用过 XMLHttpRequest 或其他网络 API,Fetch 会让你感到很熟悉。你可以参考 MDN 关于 使用 Fetch 的指南了解更多信息。

发起请求

为了从任意 URL 获取内容,你可以将 URL 传递给 fetch:

TypeScript
fetch('https://mywebsite.com/mydata.json');

Fetch 还接受一个可选的第二个参数,允许你自定义 HTTP 请求。你可能希望指定额外的请求头,或者发起一个 POST 请求:

TypeScript
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
}),
});

请查看 Fetch Request 文档 以获取完整的属性列表。

处理响应

上面的示例展示了如何发起请求。在许多情况下,你还会希望对响应做一些处理。

网络请求本质上是异步操作。Fetch 方法会返回一个 Promise,这使得编写异步代码变得很直接:

TypeScript
const getMoviesFromApi = () => {
return fetch('https://reactnative.dev/movies.json')
.then(response => response.json())
.then(json => {
return json.movies;
})
.catch(error => {
console.error(error);
});
};

你也可以在 React Native 应用中使用 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);
}
};

不要忘记捕获 fetch 可能抛出的任何错误,否则它们会被静默丢弃。

信息

默认情况下,iOS 9.0 或更高版本会强制启用 App Transport Security(ATS)。ATS 要求任何 HTTP 连接都必须使用 HTTPS。如果你需要从明文 URL(以 http 开头的 URL)获取内容,你首先需要 添加 ATS 例外。如果你事先知道需要访问哪些域名,最安全的做法是只为这些域名添加例外;如果要访问的域名要到运行时才知道,你可以 完全禁用 ATS。但请注意,从 2017 年 1 月起,Apple 的 App Store 审核会要求为禁用 ATS 提供合理说明。更多信息请参见 Apple 的文档

提示

在 Android 上,自 API Level 28 起,明文流量也会默认被阻止。可以在应用清单文件中设置 android:usesCleartextTraffic 来覆盖此行为。

使用其他网络库

React Native 内置了 XMLHttpRequest API。这意味着你可以使用依赖它的第三方库,例如 frisbeeaxios,如果你愿意,也可以直接使用 XMLHttpRequest API。

TypeScript
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();
注意

XMLHttpRequest 的安全模型与 Web 上不同,因为原生应用中没有 CORS 的概念。

WebSocket 支持

React Native 也支持 WebSockets,这是一种通过单个 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);
};

以下选项目前在 fetch 中无法正常工作

  • redirect:manual
  • credentials:omit

在 iOS 上配置 NSURLSession

对于某些应用,可能适合为在 iOS 上运行的 React Native 应用中的网络请求所使用的底层 NSURLSession 提供自定义的 NSURLSessionConfiguration。例如,你可能需要为应用发出的所有网络请求设置自定义的 user agent 字符串,或者为 NSURLSession 提供一个临时的 NSURLSessionConfiguration。函数 RCTSetCustomNSURLSessionConfigurationProvider 允许进行这类自定义。请记得在将要调用 RCTSetCustomNSURLSessionConfigurationProvider 的文件中添加以下导入:

Objective-C
#import <React/RCTHTTPRequestHandler.h>

RCTSetCustomNSURLSessionConfigurationProvider 应尽早在应用生命周期中调用,以便在 React 需要时能够立即使用,例如:

Objective-C
-(void)application:(__unused UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// 设置 RCTSetCustomNSURLSessionConfigurationProvider
RCTSetCustomNSURLSessionConfigurationProvider(^NSURLSessionConfiguration *{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
// 配置会话
return configuration;
});

// 配置 React
_bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
}