最近在使用React Native开发项目的过程中,遇到这么一个问题,在安卓应用上调试的时候,正式域名访问没有任何问题,但是如果是内网或者本地域名且使用了自签证书,请求就不通了,由于我使用的是apisauce,会出现报错[AxiosError: Network Error],在碰到这个现象后第一反应就是https证书的问题,在尝试百度、又尝试问了ChatGPT,发现GPT给出的答案也无法适用,所以大家不要过分相信ChatGPT,不过幸运的是后来通过不断变换关键词最后在Google上找到了有效答案。
解决这个问题要么提供受信的证书,要么忽略证书校验,这里我们选择忽略证书校验,接下来我们看一下具体需要怎么做。
一、增加IgnoreSSLFactory.java
在RN项目安卓原生目录下/android/app/src/main/java/com/app名/新增文件IgnoreSSLFactory.java,并编写如下代码:
package com.app;
import static android.content.ContentValues.TAG;
import android.util.Log;
import com.facebook.react.modules.network.OkHttpClientFactory;
import com.facebook.react.modules.network.OkHttpClientFactory;
import com.facebook.react.modules.network.OkHttpClientProvider;
import com.facebook.react.modules.network.ReactCookieJarContainer;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.CipherSuite;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.TlsVersion;
public class IgnoreSSLFactory implements OkHttpClientFactory {
private static final String TAG = "IgnoreSSLFactory";
@Override
public OkHttpClient createNewNetworkModuleClient() {
try {
final TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] chain,
String authType
) throws CertificateException {}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] chain,
String authType
) throws CertificateException {}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[] {};
}
},
};
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectTimeout(0, TimeUnit.MILLISECONDS)
.readTimeout(0, TimeUnit.MILLISECONDS)
.writeTimeout(0, TimeUnit.MILLISECONDS)
.cookieJar(new ReactCookieJarContainer());
builder.sslSocketFactory(
sslSocketFactory,
(X509TrustManager) trustAllCerts[0]
);
builder.hostnameVerifier(
new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
);
OkHttpClient okHttpClient = builder.build();
return okHttpClient;
} catch (Exception e) {
Log.e(TAG, e.getMessage());
throw new RuntimeException(e);
}
}
}
二、修改MainApplication.java
修改MainApplication.java文件,该文件位于/android/app/src/main/java/com/app名/目录下:
1、在头部新增如下代码:
import com.facebook.react.modules.network.OkHttpClientProvider;
2、在onCreate方法中新增如下代码:
OkHttpClientProvider.setOkHttpClientFactory(new IgnoreSSLFactory());
以我本地的项目为例,最终修改后的代码如下:
package com.app;
import com.app.MyPackage;
import android.app.Application;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactNativeHost;
import com.facebook.soloader.SoLoader;
import java.util.List;
import com.facebook.react.modules.network.OkHttpClientProvider;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost =
new DefaultReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
packages.add(new MyPackage());
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
@Override
protected boolean isNewArchEnabled() {
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
}
@Override
protected Boolean isHermesEnabled() {
return BuildConfig.IS_HERMES_ENABLED;
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
OkHttpClientProvider.setOkHttpClientFactory(new IgnoreSSLFactory());
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
DefaultNewArchitectureEntryPoint.load();
}
ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
}
文章来源于:逐梦博客