跳到主要內容

網路功能

許多行動應用程式需要從遠端 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.dev.org.tw/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.dev.org.tw/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 的安全性模型與網頁上不同,因為在原生應用程式中沒有 CORS 的概念。

WebSocket 支援

React Native 也支援 WebSockets,這是一種透過單一 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 的檔案中新增以下 import

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];
}