네이티브 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.