네이티브 fetch () 네트워크 요청 실패


146

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

1
잘 모르겠습니다. iOS 시뮬레이터를 사용하고 있는데 컴퓨터의 인터넷 연결을 사용한다고 생각했습니다.
Alek Hurst

시뮬레이터를 수동으로로드하고 사파리에서 URL을 열어보십시오
FuzzyTree

5
http-> https(가능한 경우) 문제를 해결할 가능성이 가장 높습니다
Nick Zuber

1
서버를 해당 IP에 바인딩하지 않고 IP 192.168.1.25:3000를 사용하고있었습니다ifconfigrails server --binging=192.168.1.25 --port=3000
Fabrizio Bertoglio

1
예, 모두 시도했습니다. 아무것도 나를 위해 일하지
Vigneswaran A

답변:


140

여기서 문제는 iOS가 기본적으로 HTTP 요청을 허용하지 않고 HTTPS 만 허용한다는 것입니다. HTTP 요청을 활성화하려면 이것을 다음에 추가하십시오 info.plist.

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

2
이 답변은 저에게 효과적이었습니다. React Native를 처음 사용하는 다른 사용자의 경우이 파일 (info.plist)을 xcode를 통해 편집 할 수도 있습니다. stackoverflow.com/a/38219454/1299792
Marklar

86
안드로이드는 어떻습니까? 나는 안드로이드에서도 같은 문제에 직면하고있다.
Vijay Sharma

16
바로 그거죠. 누구나 안드로이드에 대한 답변이 있습니까?
Zach Cook

1
ios / build / info.plist에 넣고 다음을 실행하면 react-native run-ios ios / build / info.plist를 덮어 쓰고 변경 사항을 종료합니다. 어떻게해야합니까?
Jorge Wander Santana Ureña

1
@ JorgeWanderSantanaUreña 수정 [your_project_folder_name] / ios / [your_project_folder_name] /In‌fo.plist
kgosse

58

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>

27
안드로이드는 어떻습니까?
arisalexis

3
내 React Native 앱의 여러 디렉토리에 여러 info.plist 파일이있는 것 같습니다. 어떤 폴더에 올바른 파일이 변경되어 있는지 알고 있습니까?
Marklar

2
@Marklar [your_project_folder_name] / ios / [your_project_folder_name] /Info.plist
Stich

<key> yourserver.com </ key>에서 로컬 호스트를 사용하는 경우 게시 할 준비가되면 변경해야합니까?
Anayo Oleru

36

나는 localhost주소를 사용하고 있었는데, 분명히 틀렸다. 에뮬레이터가있는 네트워크에서 서버의 IP 주소로 교체 한 후에 완벽하게 작동했습니다.

편집하다

Android Emulator에서 개발 시스템의 주소는 10.0.2.2입니다. 자세한 설명은 여기

Genymotion의 경우 주소는 10.0.3.2입니다. 더 많은 정보는 여기에


4
감사합니다. 아마 내가 본 유일한 응답은 안드로이드에서 작동합니다. 내 네트워크 IP 주소를 사용했는데 작동합니다. 예http://<Network IP emulator connects to>:<port where API is served>/api/tasks
Brandon Benefield

1
"http : //"를 잊지 마십시오. 그렇지 않으면 작동하지 않습니다 ... 왜 postman에서는 작동하지만 fetch에서는 작동하지 않는지 궁금했습니다.
Moucheg

@Mahmoodvcs 귀하의 답변은 많은 도움이됩니다. 감사합니다. 안드로이드 에뮬레이터를 사용하고 있습니다.
Pena Pintada

14

우리에게는 파일을 업로드하고 RN filePicker가 올바른 MIME 유형을 제공하지 않았기 때문입니다. 그것은 우리에게 유형으로 '이미지'를주었습니다. 가져 오기가 작동하도록하려면 'image / jpg'로 변경해야했습니다.

form.append(uploadFileName, {
  uri : localImage.full,
  type: 'image/jpeg',
  name: uploadFileName
 })

@JohhanSantana 아마도 원시 이미지 데이터를보고 처음부터 가져올 수 있지만 반응 네이티브 피커는 방금 '이미지'로 돌아 왔습니다.
NickJ

10

React Native Docs가 이에 대한 답을 제공합니다.

Apple이 암시 적 일반 텍스트 HTTP 리소스로드를 차단했습니다. 따라서 프로젝트의 Info.plist (또는 동등한 파일) 파일에 다음을 추가해야합니다.

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>localhost</key>
        <dict>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

네이티브 문서 반응-> 기존 앱과 통합-> 통합 테스트-> 앱 전송 보안 추가 예외


9

서버 구성에 문제가있을 수 있습니다.

Android 7.0에는 여기에 설명 된 버그가 있습니다 . Vicky Chijwani가 제안한 해결책 :

타원 곡선 프라임 256v1을 사용하도록 서버를 구성하십시오. 예를 들어 Nginx 1.10에서는 ssl_ecdh_curve prime256v1;


7

안드로이드에서도 같은 문제가 발생했지만 해결책을 찾았습니다. Android는 API 레벨 28부터 기본적으로 일반 텍스트 트래픽 (https 이외의 요청)을 차단합니다. 그러나 react-native는 디버그 모드 ( android/app/src/debug/res/xml/react_native_config.xml)에 network-security-config를 추가하여 일부 도메인 (localhost 및 AVD / Genymotion의 호스트 IP)을 정의 하는 디버그 버전 ( )에 추가합니다.이 모드는 dev 모드에서 SSL없이 사용할 수 있습니다. http 요청을 허용하기 위해 도메인을 추가 할 수 있습니다.

<?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>

기본 0.59 및 대상 SDK (28) 반응으로이 :) 나를 위해 일한
사 미라 madushan

7

"http"때문에 Android 9에서 동일한 문제가 발생 했고 AndroidManifest.xml 에서 android : usesCleartextTraffic = "true" 를 추가하여 문제가 해결되었습니다 .

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
  android:usesCleartextTraffic="true"
 .......>
 .......
</application>


2
고마워, 이것은 나를 위해 일했다. 안드로이드 API (28)에, 기본적으로 더 이상 HTTP를 지원하지 않기 때문에이 문제가 발생합니다
구이 헤르 조그에게

5

Android Emulator에서 동일한 문제가 발생하여 유효한 인증서로 외부 HTTPS URL에 액세스하려고했습니다. 하지만 반응 네이티브에서 해당 URL을 가져 오지 못했습니다.

'fetch error:', { [TypeError: Network request failed]
sourceURL: 'http://10.0.2.2:8081/index.delta?platform=android&dev=true&minify=false' }

1) 로그에서 정확한 오류를 찾으려면 먼저 앱에서 Cmd + M을 사용하여 'Debug JS Remotely'를 활성화했습니다.

2)보고 된 오류는

java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

3)이 방법을 사용하여 URL의 유효한 인증서를 추가했습니다-> 2 단계

http://lpains.net/articles/2018/install-root-ca-in-android/

이 인증서는 사용자 탭에 추가됩니다.

4) 속성 추가 android:networkSecurityConfig 속성을 AndroidManifest.xml에

네트워크 보안 구성 파일 추가 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>

이것은 작동하고 예상되는 응답을 제공합니다.


일하기 위해 방금 4 단계를 수행해야했습니다. 감사!
브루노 세라노

4

Android 에서이 문제가 발생했습니다.

URL- localhost / authToken.json-작동하지 않습니다 :(

URL-10.106.105.103 / authToken.json-작동하지 않습니다 :(

URL- http://10.106.105.103/authToken.json- 작동 :) : D

참고 ifconfig-Linux 또는 ipconfigWindows에서 시스템 IpAddress를 찾기 위해 사용


4

안드로이드 사용자 :

  1. 대체 localhost당신은 안드로이드 디바이스에서 프로젝트를 실행할 때, 로컬 호스트 안드로이드 장치를 가리키는 때문에 대신 컴퓨터, 예를의, 랜 IP 주소들 : 변화 http://localost에를http://192.168.1.123

  2. 귀하의 요청 URL이 HTTPS이고 안드로이드 장치가 프록시 미만인 경우, 당신은 사용자가 추가 한 CA 설치 한 가정 안드로이드 장치 (트림 제품군의 CA 또는 찰스의 CA 등), 확인 당신의 안드로이드 버전은 아래에 만들어 누가 (7.0) 때문에, : Android Nougat의 신뢰할 수있는 인증 기관 변경

    사용자 추가 CA
    모든 애플리케이션 데이터 보호는 Android 애플리케이션 샌드 박스의 주요 목표입니다. Android Nougat는 애플리케이션이 사용자 및 관리자 제공 CA와 상호 작용하는 방식을 변경합니다. 기본적으로 API 레벨 24를 대상으로하는 앱은 앱이 명시 적으로 선택하지 않는 한 의도적으로 CA를 준수하지 않습니다. 기본적으로 안전한 설정은 애플리케이션 공격 표면을 줄이고 네트워크 및 파일 기반 애플리케이션 데이터의 일관된 처리를 장려합니다.


3

Android의 경우 AndroidManifest.xml에서 권한을 추가하지 못했을 수 있습니다. 다음 권한을 추가해야합니다.

<uses-permission android:name="android.permission.INTERNET" /> 

오류가 발생하더라도 이미 다른 해결 방법이 있습니까?
masud_moni

@masud_moni 문제를 해결하는 방법을 찾으십니까? 메신저는 여전히 같은 문제가
라파엘 Rotiroti

@ RafaelRotiroti 예 나는 그 문제를 해결했지만, 시간이 지났지 만 기억하기가 어렵습니다. 허가를 사용했지만 여전히 문제가 발생하면 세부 사항을 공유하십시오. 나는 최선을 다해 도와 줄 것이며, 다른 사람들도 그것을 조사하도록 할 것이다
masud_moni

@masud_moni 감사합니다, ifconfig 명령을 실행 한 후 주어진 ip를 사용하여 문제를 해결했습니다. AVD는 가상 장치를 생성하므로 장치에서 127.0.0.1에 호스팅되지 않은 가상 시스템과 동일한 이론을 사용합니다. 난으로 192.168.xx IP를 사용하고 모든뿐만 아니라 잘 작동 그래서
라파엘 Rotiroti

2

비슷한 문제가 있습니다. 제 경우에는 localhost에 대한 요청이 작동하고 갑자기 중단되었습니다. 문제는 안드로이드 폰에서 Wi-Fi를 끄는 것이 었습니다.


2

이것은 나를 위해 일했습니다. 안드로이드는 특별한 유형의 IP 주소 10.0.2.2를 사용한 다음 포트 번호를 사용합니다.

import { Platform } from 'react-native';

export const baseUrl = Platform.OS === 'android' ?
    'http://10.0.2.2:3000/'
: 
'http://localhost:3000/';

1

REST API에 docker를 사용하는 경우 호스트 이름 : http://demo.test/api을 시스템 ip 주소 : 로 바꾸는 것이 http://x.x.x.x/api좋습니다. 무선 네트워크에있는 ipv4를 확인하여 IP를 얻을 수 있습니다. 당신은 또한 전화에서 무선 랜이 있어야합니다.


1

페치 API의 경우 오류 사례를 처리해야합니다.

예를 들면 다음과 같습니다.

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

0
  1. android:usesCleartextTraffic="true"AndroidManifest.xml에 줄을 추가하십시오 .

  2. 안드로이드 폴더에서 모든 디버그 폴더를 삭제하십시오.


0

이것을 사용하여 처리 할 수 ​​있습니다.

catch((error) => {
      this.setState({
        typing_animation_button: false,
      });
      console.log(error);
      if ('Timeout' || 'Network request failed') {
        toast_show = true;
        toast_type = 'error';
        toast_text = 'Network failure';
      }
      this.setState({
        disable_button: false,
      });
    });

-1

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

-1

Android 디바이스의 경우 프로젝트 루트 폴더로 이동하여 다음 명령을 실행하십시오.

adb reverse tcp:[your_own_server_port] tcp:[your_own_server_port]

예를 들어 adb reverse tcp:8088 tcp:8088

그러면 실제 장치 (예 : Android 전화)가 http : // localhost : [your_own_server_port] 주소에서 개발 시스템 (예 : 컴퓨터)에서 실행중인 로컬 호스트 서버를 청취하게됩니다 .

그런 http:localhost:[your_port] /your_api다음 react-native fetch() 호출 에서 직접 사용할 수 있습니다 .


-1

Android의 경우 android : networkSecurityConfig = "@ xml / network_security_config"를 AndroidManifest.xml의 애플리케이션 태그에 다음과 같이 추가하십시오.

    <?xml version="1.0" encoding="utf-8"?>
    <manifest ... >
        <application android:networkSecurityConfig="@xml/network_security_config"
                        ... >
            ...
        </application>
    </manifest>

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>

<!-- let application to use http request -->
<base-config cleartextTrafficPermitted="true" />
</network-security-config>

자세히 설명해 주시겠습니까? 어떻게 작동하는지 궁금합니다.
ganeshdeshmukh

의견을 수정했습니다. 도움이 되길 바랍니다
xyz

-5

예:

return fetch('http://<your ip>')
  .then((response) => response.json())
  .then((responseJson) => {
    console.log(responseJson)
  })
  .catch((error) => {
    console.error(error);
  });
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.