跳到主要内容

网络

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

使用 Fetch

React Native 提供了 Fetch API 以满足您的联网需求。如果您以前使用过 XMLHttpRequest 或其他联网 API,您会对 Fetch 感到熟悉。您可以参考 MDN 关于 使用 Fetch 的指南以获取更多信息。

发起请求

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

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

Fetch 还接受一个可选的第二个参数,允许您自定义 HTTP 请求。您可能需要指定其他标头,或发出 POST 请求

tsx
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,使编写以异步方式工作的代码变得简单明了

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

您还可以在 React Native 应用中使用 async / await 语法

tsx
const getMoviesFromApiAsync = async () => {
try {
const response = await fetch(
'https://reactnative.net.cn/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 来覆盖此行为。

使用其他网络库

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

tsx
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 还支持 WebSocket,这是一种通过单个 TCP 连接提供全双工通信通道的协议。

tsx
const ws = new WebSocket('ws://host.com/path');

ws.onopen = () => {
// connection opened
ws.send('something'); // send a message
};

ws.onmessage = e => {
// a message was received
console.log(e.data);
};

ws.onerror = e => {
// an error occurred
console.log(e.message);
};

ws.onclose = e => {
// connection closed
console.log(e.code, e.reason);
};

以下选项目前无法与 fetch 一起使用

  • redirect:manual
  • credentials:omit

在 iOS 上配置 NSURLSession

对于某些应用程序,为在 iOS 上运行的 React Native 应用程序中的网络请求使用的底层 NSURLSession 提供自定义 NSURLSessionConfiguration 可能是合适的。例如,可能需要为来自应用程序的所有网络请求设置自定义用户代理字符串,或者为 NSURLSession 提供临时的 NSURLSessionConfiguration。函数 RCTSetCustomNSURLSessionConfigurationProvider 允许进行此类自定义。请记住将以下导入添加到将调用 RCTSetCustomNSURLSessionConfigurationProvider 的文件中

objectivec
#import <React/RCTHTTPRequestHandler.h>

RCTSetCustomNSURLSessionConfigurationProvider 应该在应用程序生命周期的早期调用,以便在 React 需要时随时可用,例如

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

// set RCTSetCustomNSURLSessionConfigurationProvider
RCTSetCustomNSURLSessionConfigurationProvider(^NSURLSessionConfiguration *{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
// configure the session
return configuration;
});

// set up React
_bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
}