问题
如标题,我想向我的后端发送一个请求,但是提示网络错误。但是并不是对全部的url(差别域名大概ip地址)都是提示错误,有部分url能够成功获取数据。已知利用的后台都是精确可用的。
- axios
- .get('http://xxx.xxx.xxx.xxx:3000/api/...', {
- headers: {
- Accept:
- 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
- 'Content-Type': 'application/json',
- 'user-agent':
- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/',
- 'Access-Control-Allow-Origin': '*', // 允许跨域
- },
- })
- .then(res => {
- console.log(res);
- })
- .catch(err => {
- console.log(err);
- });
复制代码
问题分析
看了很多中文答案,但是都不凑效,那么就只有对问题进行分析了
- 起首无论是控制台还是flipper如许的debug工具,都未详细说明为什么网络请求失败,以是不清除详细缘由。
- 利用flipper的网络检测工具,发现这些错误请求压根就没有发送出去,网络请求一栏中全部都是空缺,以是应该是RN把这个请求拦截了,与后端服务器无关。
- http和https测试后均表现可以成功发送部分请求,说明错误与协议无关。
- 无论利用ip地址还是域名作为url,都有成功发送请求的实例,说明与用ip地址大概域名是无关的。
- 当然fetch和axios都同时成功大概失败,那么自然说明与请求的方法无关。
- 什么请求头啊、跨域什么都也弄了的,以是与这个无关
这就很神奇了,太神奇了!这是个什么缘由。只有从stackoverflow之类的地方看看国外大神了,他们也说到了一个大概原因;
- ios中仅支持https,不外android没有这个问题。过!
- 没有设置<uses-permission android:name="android.permission.INTERNET" />
- 没有设置form范例
- 等等都没用实际作用的
后面看到github相干issue发现大概与ca证书有关,我的后端没有备案只用利用ip地址访问,同时为了安全我又申请了zeroSSL的相干证书,大概就是与ca证书不被这个安卓辨认的原因,但是链接被拒绝的原因。
解决问题
没有证书,我就给它证书。参考相干内容(须要翻墙)对ca进行设置。
1.起首在android/app/src/main/AndroidManifest.xml中进行修改
- <manifest xmlns:android="http://schemas.android.com/apk/res/android">
- <uses-permission android:name="android.permission.INTERNET" />
- <application
- android:usesCleartextTraffic="true"
- <-- 增加下面一行,标志出安全文件的xml位置 -->
- android:networkSecurityConfig="@xml/network_security_config"
- android:name=".MainApplication"
- android:label="@string/app_name"
- android:icon="@mipmap/ic_launcher"
- android:roundIcon="@mipmap/ic_launcher_round"
- android:allowBackup="false"
- android:theme="@style/AppTheme">
- <activity
- android:name=".MainActivity"
- android:label="@string/app_name"
- android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
- android:launchMode="singleTask"
- android:windowSoftInputMode="adjustResize"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
- </manifest>
复制代码 2.然后android/app/src/main/res/xml/network_security_config.xml(没有就创建一个)中写下ca的相干安全设置
- <network-security-config>
- <base-config cleartextTrafficPermitted="true">
- <trust-anchors>
- <!-- 信任系统默认的CAs -->
- <!-- <certificates src="system" />-->
- <!-- 信任用户安装的CAs -->
- <certificates src="@raw/certificate" />
- </trust-anchors>
- </base-config>
- </network-security-config>
复制代码 3.然后进入到android/app/src/main/res/raw文件夹(没有就创建),把目的服务器的certificate.pem大概certificate.crt证书放到这个文件夹
4.末了npm run android下令重新构建一下就好了。
当然上述的文件夹啊、文件位置什么的都可以本身决定,然后就能解决问题了!
参考
参考c网络安全设置 | App quality | Android Developers
javascript - React Native fetch() Network Request Failed - Stack OverflowHTTP Fetch fails with "TypeError: Network request failed" => Resolved · Issue #32931 · facebook/react-native · GitHub
HTTP Fetch fails with "TypeError: Network request failed" => Resolved · Issue #32931 · facebook/react-native · GitHub
另一个小问题
开发过程中须要访问localhost:3000后端,但是也会提示上面类似错误,但是实际上是因为虚拟机与本地电脑桥接问题
解决方案如下
- 利用"adb reverse tcp:3000 tcp:3000",将两个端口映射一下
- 再就是比较简朴的,用10.0.2.2这个ip地址替代localhost就好了
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |