我目前正在使用React Native开发Android应用,通过fetch()函数来进行API请求。但是,由于端点没有SSL证书,请求失败了。在iOS上,我通过修改一些Xcode文件来解决这个问题。 有没有办法在Android上忽略SSL证书检查?
我目前正在使用React Native开发Android应用,通过fetch()函数来进行API请求。但是,由于端点没有SSL证书,请求失败了。在iOS上,我通过修改一些Xcode文件来解决这个问题。 有没有办法在Android上忽略SSL证书检查?
/**
* Disables the SSL certificate checking for new instances of {@link HttpsURLConnection} This has been created to
* aid testing on a local box, not for use on production.
*/
private static void disableSSLCertificateChecking() {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
// Not implemented
}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
// Not implemented
}
} };
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
在这里找到了这篇文章:https://gist.github.com/aembleton/889392。不太确定它是否有效,但至少是一个开始!
我也遇到了同样的问题。我使用了rn-fetch-blob库,并将下面的代码粘贴到index.js中。
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
import RNFetchBlob from 'rn-fetch-blob';
AppRegistry.registerComponent(appName, () => App);
const Fetch = RNFetchBlob.polyfill.Fetch
// replace built-in fetch
window.fetch = new Fetch({
// enable this option so that the response data conversion handled automatically
auto : true,
// when receiving response data, the module will match its Content-Type header
// with strings in this array. If it contains any one of string in this array,
// the response body will be considered as binary data and the data will be stored
// in file system instead of in memory.
// By default, it only store response data to file system when Content-Type
// contains string `application/octet`.
binaryContentTypes : [
'image/',
'video/',
'audio/',
'foo/',
],
trusty : true
}).build()
import android.annotation.SuppressLint;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class MainApplication extends Application implements ReactApplication {
@Override
public void onCreate() {
super.onCreate();
handleSSLHandshake();
SoLoader.init(this, /* native exopackage */ false);
initializeFlipper(this); // Remove this line if you don't want Flipper enabled
}
/**
* Enables https connections
*/
@SuppressLint("TrulyRandom")
public static void handleSSLHandshake() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
} catch (Exception ignored) {
}
}
}
注意:这是一个不太规范的解决方案
你可以修补webview包
前往node_modules/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java
在onReceivedSslError中更改handler.cancel()为handler.proceed(),像这样
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
// before: handler.cancel();
handler.proceed();
}