J'ai rencontré l'erreur suivante. Actuellement, je développe une application Android avec React Native et je prévois donc utiliser fetch pour effectuer une demande de publication pour moi.
fetch("https://XXreachable-domainXX.de/api/test", {
method: "post",
body: JSON.stringify({
param: 'param',
param1: 'param',
})
}
)
.then((response) = > response.json()
)
.
then((responseData) = > {
ToastAndroid.show(
"Response Body -> " + JSON.stringify(responseData.message), ToastAndroid.SHORT
)
})
.
catch((error) = > {
console.warn(error);
})
;
L'application génère maintenant une erreur:
TypeError: la requête réseau a échoué
Lorsque je modifie le code en une requête GET, tout fonctionne correctement dans le navigateur avec un retour window.alert (), il est cool et l'extension chromée Postman renvoie correctement les données.
L'erreur de ce React Native est plutôt inutile, vous devez donc obtenir en premier l'erreur réelle sous-jacente. Le moyen le plus simple consiste à écrire un petit programme natif qui exécuterait simplement la même requête en utilisant HttpsURLConnection
.
Pour moi, l'erreur réelle était Java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
Qui a une solution bien connue: https://developer.Android.com/training/articles/security-ssl.html#MissingCa
C’est très probablement votre cas également, étant donné que les navigateurs et Postman n’ont aucun problème avec la demande. Pour le vérifier, lancez openssl s_client -connect XXreachable-domainXX.de:443 -showcerts
. S'il y a des erreurs de certificat, corrigez-les d'abord, cela pourrait vous épargner du temps pour écrire le programme natif.
Edit: en fait, le moyen le plus simple de voir toutes les erreurs Android sous-jacentes pour réagir natif consiste simplement à exécuter 'adb logcat' dans le terminal
Développer avec Windows OS/serveur intégré PHP/Android sur le périphérique react-native:
ipconfig
), par exemple. 172.16.0.10fetch
utiliser cette URL et le port approprié (fetch('http://172.16.0.10:8000/api/foo)
)php -S 172.16.0.10:8000 ...
Cela a résolu le problème de connexion entre le téléphone Android et le serveur local pour moi.
Si vous avez eu cette erreur et que vous êtes certain que tout fonctionne bien et vous utilisez un émulateur, fermez-le simplement et relancez-le.
Il devrait fonctionner maintenant.
Cela se produit généralement après une longue période d'hibernation du système.
Si vous rencontrez ce problème sur l'émulateur, assurez-vous également de le tester sur le périphérique. Cela ne se produit probablement pas là-bas.
Juste pour que vous sachiez qu'il n'y a rien d'inquiétant si vous pouvez y remédier.
J'ai eu ce problème sur Android en raison d'un certificat expiré. Le message d'erreur que j'ai eu était com.Android.org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate: Certificate expired at Fri Sep 29 16:33:39 EDT 2017 (compared to Fri Dec 08 14:10:58 EST 2017)
.
J'ai pu confirmer cela avec digicert.com .
Malheureusement, j’ai dû creuser assez profondément dans le code React Native et déboguer le code XHR dans le paquet (index.Android.bundle)
afin de trouver le message d’erreur et l’URL en question, car c’était dans une partie de mon code de journalisation, ce que je n’avais évidemment pas fait. t Connectez-vous également à la console. :)
J'ai été aidé par ce commentaire sur le problème GitHub .
Vérifiez deux cas ci-dessous
Il a mangé 2 heure avec la deuxième raison.
J'ai eu un problème majeur en faisant la même chose sur l'émulateur Android. Sur iOS, il était nécessaire d’approuver le domaine dans info.plist. Pour être clair, je tentais de me connecter à mon API hébergée sur le Web .NET.
La solution consistait à s'assurer que les données de publication étaient paramétrées (je suis à peu près sûr que c'est un mot).
export const loginUser = ({ userName, password }) => {
const data = `UserName=${userName}&Password=${password}&grant_type=password`
return (dispatch) => {
dispatch({ type: LOGIN_USER })
fetch(URL_LOGIN, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: data
// body: {
// UserName: userName,
// Password: password,
// grant_type: 'password'
// }
})
.then((response) => {
loginUserSuccess(dispatch, response)
})
.catch((response) => {
loginUserFailed(dispatch, response)
})
};
};