네이티브 fetch () 네트워크 요청 실패
react-native init
(RN 버전 0.29.1)을 사용하여 새로운 프로젝트를 만들고 렌더 메소드에 공개 페이스 북 데모 영화 API에 가져 오기를 넣으면을 던집니다 Network Request Failed
. 매우 쓸모없는 스택 추적이 있으며 크롬 콘솔에서 네트워크 요청을 디버깅 할 수 없습니다. 내가 보내는 패치는 다음과 같습니다.
fetch('http://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
return responseJson.movies;
})
.catch((error) => {
console.error(error);
});
여기서 문제는 iOS가 기본적으로 HTTP 요청을 허용하지 않고 HTTPS 만 허용한다는 것입니다. HTTP 요청을 활성화하려면 이것을 다음에 추가하십시오 info.plist
.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
http에 모든 도메인을 허용하지 않는 것이 좋습니다. 필요한 도메인 만 예외로 설정하십시오.
출처 : iOS 9 및 OSX 10.11에서 앱 전송 보안 예외 구성
앱의 info.plist 파일에 다음을 추가하십시오.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>yourserver.com</key>
<dict>
<!--Include to allow subdomains-->
<key>NSIncludesSubdomains</key>
<true/>
<!--Include to allow HTTP requests-->
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<!--Include to specify minimum TLS version-->
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
나는 localhost
주소를 사용하고 있었는데, 분명히 틀렸다. 에뮬레이터가있는 네트워크에서 서버의 IP 주소로 교체 한 후에 완벽하게 작동했습니다.
편집하다
Android Emulator에서 개발 시스템의 주소는 10.0.2.2
입니다. 자세한 설명은 여기
Genymotion의 경우 주소는 10.0.3.2
입니다. 더 많은 정보는 여기에
서버 구성에 문제가있을 수 있습니다.
Android 7.0에는 여기에 설명 된 버그가 있습니다 . Vicky Chijwani가 제안한 해결책 :
타원 곡선 프라임 256v1을 사용하도록 서버를 구성하십시오. 예를 들어 Nginx 1.10에서는 ssl_ecdh_curve prime256v1;
React Native Docs가 이에 대한 답을 제공합니다.
Apple has blocked implicit cleartext HTTP resource loading. So we need to add the following our project's Info.plist (or equivalent) file.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
For us it was because we were uploading a file and the RN filePicker did not give the proper mime type. It just gave us 'image' as the type. We needed to change it to 'image/jpg' to get the fetch to work.
form.append(uploadFileName, {
uri : localImage.full,
type: 'image/jpeg',
name: uploadFileName
})
I got the same issue on Android but I managed to find a solution for it. Android is blocking cleartext traffic (non-https-requests) since API Level 28 by default. However, react-native adds a network-security-config to the debug version (android/app/src/debug/res/xml/react_native_config.xml
) which defines some domains (localhost, and the host IPs for AVD / Genymotion), which can be used without SSL in dev mode. You can add your domain there to allow http requests.
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="false">localhost</domain>
<domain includeSubdomains="false">10.0.2.2</domain>
<domain includeSubdomains="false">10.0.3.2</domain>
<domain includeSubdomains="true">dev.local</domain>
</domain-config>
</network-security-config>
For Android, you may have missed to add permission in AndroidManifest.xml Need to add the following permission.
<uses-permission android:name="android.permission.INTERNET" />
I have similar problem. In my case requests to localhost was working and suddenly stopped. It turn out that the problem was that I was turn off my wifi on my android phone.
I was having this problem for Android-
URL- localhost/authToken.json - didn't work :(
URL- 10.106.105.103/authToken.json - didn't work :(
URL- http://10.106.105.103/authToken.json - worked :) :D
Note- Use ifconfig
on Linux or ipconfig
on Windows to find machine IpAddress
For Android user:
Replace
localhost
s to a Lan IP addresses because when you run the project on an Android device, localhost is pointing to the Android device, instead of your computer, example: changehttp://localost
tohttp://192.168.1.123
- If your request URL is HTTPS and your Android device is under a proxy, assume you have installed User-added CA(like burp suite's CA or Charles's CA) in your Android device, make sure your Android version is below Nougat(7.0), because: Changes to Trusted Certificate Authorities in Android Nougat
User-added CAs
Protection of all application data is a key goal of the Android application sandbox. Android Nougat changes how applications interact with user- and admin-supplied CAs. By default, apps that target API level 24 will—by design—not honor such CAs unless the app explicitly opts in. This safe-by-default setting reduces application attack surface and encourages consistent handling of network and file-based application data.
I came across the same issue on Android Emulator, where I tried to access an external HTTPS URL with a valid certificate. But fetching that URL in react-native failed
'fetch error:', { [TypeError: Network request failed]
sourceURL: 'http://10.0.2.2:8081/index.delta?platform=android&dev=true&minify=false' }
1) To find out the exact error in the logs, I first enabled 'Debug JS Remotely' using Cmd + M on the app
2) The error reported was
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
3) I added the URL's valid certificate using this method -> STEP 2
http://lpains.net/articles/2018/install-root-ca-in-android/
This certificate gets added to the User tab.
4) Add the attribute android:networkSecurityConfig
attribute to AndroidManifest.xml
Add a Network Security Configuration file res/xml/network_security_config.xml:
<network-security-config>
<base-config>
<trust-anchors>
<certificates src="user"/>
<certificates src="system"/>
</trust-anchors>
</base-config>
</network-security-config>
This should work and give you an expected response.
This worked for me, android uses a special type of IP address 10.0.2.2 then port number
import { Platform } from 'react-native';
export const baseUrl = Platform.OS === 'android' ?
'http://10.0.2.2:3000/'
:
'http://localhost:3000/';
if you use docker for the REST api, a working case for me was to replace hostname: http://demo.test/api
with the machine ip address: http://x.x.x.x/api
. You can get the IP from checking what ipv4 you have on your wireless network. You should have also the wifi from phone on.
You should handle the error case in .then for fetch API.
For example:
fetch(authURl,{ method: 'GET'})
.then((response) => {
const statusCode = response.status;
console.warn('status Code',statusCode);
if(statusCode==200){
//success code
}else{
//handle other error code
}
},(err) => {
console.warn('error',err)
})
.catch((error) => {
console.error(error);
return error;
});
Just you have Changes in Fetch....
fetch('http://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
/*return responseJson.movies; */
alert("result:"+JSON.stringify(responseJson))
this.setState({
dataSource:this.state.dataSource.cloneWithRows(responseJson)
})
}).catch((error) => {
console.error(error);
});
For android, add android:networkSecurityConfig="@xml/network_security_config" in tag
network_security_config.xml
<?xml version='1.0' encoding='utf-8'?>
<network-security-config>
<debug-overrides>
<trust-anchors>
<!-- Trust user added CAs while debuggable only -->
<certificates src="user" />
</trust-anchors>
</debug-overrides>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
For Android devices, go to your project root folder and run the command:
adb reverse tcp:[your_own_server_port] tcp:[your_own_server_port]
e.g., adb reverse tcp:8088 tcp:8088
This will make your physical device(i.e. Android phone) listen to the localhost server running on your development machine (i.e. your computer) on address http://localhost:[your_own_server_port].
After that, you can directly use http:localhost:[your_port] /your_api
in your react-native fetch(
) call.
Example:
return fetch('http://<your ip>')
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson)
})
.catch((error) => {
console.error(error);
});
참고URL : https://stackoverflow.com/questions/38418998/react-native-fetch-network-request-failed
'programing tip' 카테고리의 다른 글
폴더가없는 경우 파일과 폴더를 어떻게 만듭니 까? (0) | 2020.07.15 |
---|---|
GET 데이터도 HTTPS로 암호화됩니까? (0) | 2020.07.15 |
Oracle SELECT TOP 10 레코드 (0) | 2020.07.15 |
MySQL의 기존 행에 대한 Insert Statement 가져 오기 (0) | 2020.07.15 |
특정 커밋 이후 커밋을 나열하는 방법은 무엇입니까? (0) | 2020.07.15 |