Sieć
Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt. Znalazłeś błąd? Zgłoś problem →
Wiele aplikacji mobilnych musi ładować zasoby ze zdalnych adresów URL. Możesz potrzebować wysłać żądanie POST do interfejsu REST API lub pobrać fragment statycznej treści z innego serwera.
Korzystanie z Fetch
React Native udostępnia Fetch API do obsługi sieci. Fetch będzie znajomy jeśli wcześniej używałeś XMLHttpRequest lub innych interfejsów sieciowych. Dodatkowe informacje znajdziesz w przewodniku MDN Korzystanie z Fetch.
Wysyłanie żądań
Aby pobrać zawartość z dowolnego URL, możesz przekazać adres do funkcji fetch:
fetch('https://mywebsite.com/mydata.json');
Fetch przyjmuje również opcjonalny drugi argument umożliwiający dostosowanie żądania HTTP. Możesz chcieć dodać dodatkowe nagłówki lub wykonać żądanie POST:
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
}),
});
Pełną listę właściwości znajdziesz w dokumentacji Fetch Request.
Obsługa odpowiedzi
Powyższe przykłady pokazują jak wysłać żądanie. W wielu przypadkach będziesz chciał coś zrobić z otrzymaną odpowiedzią.
Komunikacja sieciowa jest z natury operacją asynchroniczną. Metoda fetch zwraca Promise, co ułatwia pisanie kodu działającego asynchronicznie:
const getMoviesFromApi = () => {
return fetch('https://reactnative.dev/movies.json')
.then(response => response.json())
.then(json => {
return json.movies;
})
.catch(error => {
console.error(error);
});
};
Możesz również użyć składni async / await w aplikacji React Native:
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);
}
};
Nie zapomnij przechwycić potencjalnych błędów zgłaszanych przez fetch, w przeciwnym razie zostaną one cicho zignorowane.
- TypeScript
- JavaScript
Domyślnie iOS 9.0 i nowsze wymuszają App Transport Security (ATS). ATS wymaga, aby wszystkie połączenia HTTP korzystały z HTTPS. Jeśli potrzebujesz pobrać dane z niezaszyfrowanego adresu URL (rozpoczynającego się od
http), musisz najpierw dodać wyjątek ATS. Jeśli znasz z wyprzedzeniem domeny, do których potrzebujesz dostępu, bezpieczniej jest dodać wyjątki tylko dla nich; jeśli domeny nie są znane do czasu uruchomienia aplikacji, możesz całkowicie wyłączyć ATS. Pamiętaj jednak, że od stycznia 2017 przegląd aplikacji w App Store firmy Apple wymaga uzasadnienia wyłączenia ATS. Więcej informacji znajdziesz w dokumentacji Apple.
W systemie Android, począwszy od poziomu API 28, niezaszyfrowany ruch jest domyślnie blokowany. To zachowanie można zmienić, ustawiając
android:usesCleartextTrafficw pliku manifestu aplikacji.
Korzystanie z innych bibliotek sieciowych
API XMLHttpRequest jest wbudowane w React Native. Oznacza to, że możesz używać bibliotek stron trzecich takich jak frisbee czy axios, które na nim polegają, lub bezpośrednio używać API XMLHttpRequest jeśli wolisz.
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();
Model bezpieczeństwa dla XMLHttpRequest różni się od tego w sieci, ponieważ w aplikacjach natywnych nie istnieje koncepcja CORS.
Obsługa WebSocket
React Native obsługuje również WebSockets, protokół zapewniający pełny duplex kanałów komunikacyjnych przez pojedyncze połączenie TCP.
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);
};
Znane problemy z fetch i uwierzytelnianiem opartym na ciasteczkach
Następujące opcje obecnie nie działają z fetch
-
redirect:manual -
credentials:omit
-
Używanie nagłówków o tej samej nazwie w Androidzie spowoduje, że dostępny będzie tylko ostatni. Tymczasowe rozwiązanie: https://github.com/facebook/react-native/issues/18837#issuecomment-398779994.
-
Uwierzytelnianie oparte na ciasteczkach jest obecnie niestabilne. Lista znanych problemów: https://github.com/facebook/react-native/issues/23185
-
Przynajmniej w iOS, przy przekierowaniu typu
302, jeśli występuje nagłówekSet-Cookie, ciasteczko nie jest ustawiane poprawnie. Ponieważ przekierowania nie można obsłużyć ręcznie, może to powodować nieskończoną pętlę żądań gdy przekierowanie wynika z wygasłej sesji.
Konfiguracja NSURLSession w iOS
W niektórych aplikacjach może być wskazane dostarczenie niestandardowej konfiguracji NSURLSessionConfiguration dla bazowej sesji NSURLSession używanej do żądań sieciowych w aplikacji React Native działającej na iOS. Na przykład może zaistnieć potrzeba ustawienia niestandardowego ciągu agenta użytkownika dla wszystkich żądań sieciowych lub dostarczenia NSURLSession tymczasowej konfiguracji NSURLSessionConfiguration. Funkcja RCTSetCustomNSURLSessionConfigurationProvider umożliwia taką konfigurację. Pamiętaj o dodaniu następującego importu w pliku gdzie wywoływana będzie RCTSetCustomNSURLSessionConfigurationProvider:
#import <React/RCTHTTPRequestHandler.h>
RCTSetCustomNSURLSessionConfigurationProvider powinna być wywołana wcześnie w cyklu życia aplikacji, aby była dostępna gdy React jej potrzebuje, na przykład:
-(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];
}