联网
许多移动应用需要从远程 URL 加载资源。你可能想要向 REST API 发出 POST 请求,或者可能需要从另一台服务器获取一大块静态内容。
¥Many mobile apps need to load resources from a remote URL. You may want to make a POST request to a REST API, or you may need to fetch a chunk of static content from another server.
使用获取
¥Using Fetch
React Native 提供了 获取 API 来满足你的网络需求。如果你以前使用过 XMLHttpRequest
或其他网络 API,那么 Fetch 会显得很熟悉。你可以参考 MDN 的 使用获取 指南以获取更多信息。
¥React Native provides the Fetch API for your networking needs. Fetch will seem familiar if you have used XMLHttpRequest
or other networking APIs before. You may refer to MDN's guide on Using Fetch for additional information.
发出请求
¥Making requests
为了从任意 URL 获取内容,你可以传递要获取的 URL:
¥In order to fetch content from an arbitrary URL, you can pass the URL to fetch:
fetch('https://mywebsite.com/mydata.json');
Fetch 还采用可选的第二个参数,允许你自定义 HTTP 请求。你可能想要指定其他标头,或发出 POST 请求:
¥Fetch also takes an optional second argument that allows you to customize the HTTP request. You may want to specify additional headers, or make a POST request:
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
}),
});
查看 获取请求文档 的完整属性列表。
¥Take a look at the Fetch Request docs for a full list of properties.
处理响应
¥Handling the response
上述示例展示了如何提出请求。在许多情况下,你需要对响应执行某些操作。
¥The above examples show how you can make a request. In many cases, you will want to do something with the response.
网络本质上是一种异步操作。Fetch 方法将返回 Promise,这使得编写以异步方式工作的代码变得简单:
¥Networking is an inherently asynchronous operation. Fetch method will return a Promise that makes it straightforward to write code that works in an asynchronous manner:
const getMoviesFromApi = () => {
return fetch('https://rn.nodejs.cn/movies.json')
.then(response => response.json())
.then(json => {
return json.movies;
})
.catch(error => {
console.error(error);
});
};
你还可以在 React Native 应用中使用 async
/ await
语法:
¥You can also use the async
/ await
syntax in a React Native app:
const getMoviesFromApiAsync = async () => {
try {
const response = await fetch(
'https://rn.nodejs.cn/movies.json',
);
const json = await response.json();
return json.movies;
} catch (error) {
console.error(error);
}
};
不要忘记捕获 fetch
可能抛出的任何错误,否则它们将被默默删除。
¥Don't forget to catch any errors that may be thrown by fetch
, otherwise they will be dropped silently.
- TypeScript
- JavaScript
默认情况下,iOS 9.0 或更高版本强制执行应用传输安全 (ATS)。ATS 需要任何 HTTP 连接才能使用 HTTPS。如果你需要从明文 URL(以
http
开头的 URL)获取,你首先需要 添加 ATS 例外。如果你提前知道需要访问哪些域,则仅为这些域添加例外会更安全;如果这些域直到运行时才知道,你可以 完全禁用 ATS。但请注意,从 2017 年 1 月起,Apple 的 App Store 审查将要求禁用 ATS 提供合理的理由.请参阅 苹果的文档 了解更多信息。¥By default, iOS 9.0 or later enforce App Transport Security (ATS). ATS requires any HTTP connection to use HTTPS. If you need to fetch from a cleartext URL (one that begins with
http
) you will first need to add an ATS exception. If you know ahead of time what domains you will need access to, it is more secure to add exceptions only for those domains; if the domains are not known until runtime you can disable ATS completely. Note however that from January 2017, Apple's App Store review will require reasonable justification for disabling ATS. See Apple's documentation for more information.
在 Android 上,从 API 级别 28 开始,默认情况下也会阻止明文流量。可以通过在应用清单文件中设置
android:usesCleartextTraffic
来覆盖此行为。¥On Android, as of API Level 28, clear text traffic is also blocked by default. This behaviour can be overridden by setting
android:usesCleartextTraffic
in the app manifest file.
使用其他网络库
¥Using Other Networking Libraries
XMLHttp 请求 API 内置于 React Native 中。这意味着你可以使用依赖于它的第三方库,例如 frisbee 或 axios,或者如果你愿意,也可以直接使用 XMLHttpRequest API。
¥The XMLHttpRequest API is built into React Native. This means that you can use third party libraries such as frisbee or axios that depend on it, or you can use the XMLHttpRequest API directly if you prefer.
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 的概念。
¥The security model for XMLHttpRequest is different than on web as there is no concept of CORS in native apps.
WebSocket 支持
¥WebSocket Support
React Native 还支持 WebSockets,该协议通过单个 TCP 连接提供全双工通信通道。
¥React Native also supports WebSockets, a protocol which provides full-duplex communication channels over a single TCP connection.
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
和基于 cookie 的身份验证的已知问题
¥Known Issues with fetch
and cookie based authentication
以下选项目前不适用于 fetch
¥The following options are currently not working with fetch
-
redirect:manual
-
credentials:omit
-
Android 上具有相同名称的标头将导致仅显示最新的标头。可以在这里找到临时解决方案:https://github.com/facebook/react-native/issues/18837#issuecomment-398779994。
¥Having same name headers on Android will result in only the latest one being present. A temporary solution can be found here: https://github.com/facebook/react-native/issues/18837#issuecomment-398779994.
-
基于 Cookie 的身份验证目前不稳定。你可以查看此处提出的一些问题:https://github.com/facebook/react-native/issues/23185
¥Cookie based authentication is currently unstable. You can view some of the issues raised here: https://github.com/facebook/react-native/issues/23185
-
至少在 iOS 上,当通过
302
重定向时,如果存在Set-Cookie
标头,则 cookie 未正确设置。由于无法手动处理重定向,因此如果重定向是过期会话的结果,则可能会导致出现无限请求的情况。¥As a minimum on iOS, when redirected through a
302
, if aSet-Cookie
header is present, the cookie is not set properly. Since the redirect cannot be handled manually this might cause a scenario where infinite requests occur if the redirect is the result of an expired session.
在 iOS 上配置 NSURLSession
¥Configuring NSURLSession on iOS
对于某些应用,为底层 NSURLSession
提供自定义 NSURLSessionConfiguration
可能是合适的,该 NSURLSession
用于在 iOS 上运行的 React Native 应用中的网络请求。例如,可能需要为来自应用的所有网络请求设置自定义用户代理字符串,或者为 NSURLSession
提供临时 NSURLSessionConfiguration
。功能 RCTSetCustomNSURLSessionConfigurationProvider
允许进行此类定制。请记住将以下导入添加到将调用 RCTSetCustomNSURLSessionConfigurationProvider
的文件中:
¥For some applications it may be appropriate to provide a custom NSURLSessionConfiguration
for the underlying NSURLSession
that is used for network requests in a React Native application running on iOS. For instance, one may need to set a custom user agent string for all network requests coming from the app or supply NSURLSession
with an ephemeral NSURLSessionConfiguration
. The function RCTSetCustomNSURLSessionConfigurationProvider
allows for such customization. Remember to add the following import to the file in which RCTSetCustomNSURLSessionConfigurationProvider
will be called:
#import <React/RCTHTTPRequestHandler.h>
RCTSetCustomNSURLSessionConfigurationProvider
应在应用生命周期的早期调用,以便在 React 需要时可以随时使用,例如:
¥RCTSetCustomNSURLSessionConfigurationProvider
should be called early in the application life cycle such that it is readily available when needed by React, for instance:
-(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];
}