【发布时间】:2021-08-21 18:45:05
【问题描述】:
嗨,我有这个 https api,它的行为有点奇怪,所以我有这样的 fetch/api 函数
我的 react 原生版本
"axios": "^0.21.1",
"prop-types": "^15.7.2",
"react": "17.0.1",
"react-native": "0.64.1",
try {
let result = await axios({
method: 'POST',
url: 'https://my.service.com/authService/accounts/login',
data: {
userid: 'username',
password: 'password',
},
headers: {
ContentType: 'application/JSON',
Accept: 'application/json',
},
});
console.log(result);
} catch (error) {
console.log(error, 'error');
}
所以当我使用 iOS 模拟器对其进行测试时,它工作得很好。但是当我用 android 测试它时,它给了我这个错误
是否有针对这种情况的任何特定配置,(我已经使用 cleartextTrafficPermitted="true" 但由于我的 api 是 HTTPS,所以它不起作用)。
react-native-ssl-pinning 它适用于 android 但不适用于 iOS。而且我真的不想使用这些库,因为自动链接不起作用
更新:我尝试实施此解决方案
package com.test; // replace app-name
import com.facebook.react.modules.network.OkHttpClientFactory;
import com.facebook.react.modules.network.OkHttpClientProvider;
import com.facebook.react.modules.network.ReactCookieJarContainer;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import java.net.*;
import java.io.*;
import okhttp3.OkHttpClient;
import okhttp3.*;
import java.util.List;
import java.util.ArrayList;
public class CustomClientFactory implements OkHttpClientFactory {
@Override
public OkHttpClient createNewNetworkModuleClient() {
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.cipherSuites(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256)
.build();
List<ConnectionSpec> specs = new ArrayList<>();
specs.add(spec);
specs.add(ConnectionSpec.COMPATIBLE_TLS);
specs.add(ConnectionSpec.CLEARTEXT);
OkHttpClient.Builder client = new OkHttpClient.Builder().connectionSpecs(specs)
.connectTimeout(0, TimeUnit.MILLISECONDS).readTimeout(0, TimeUnit.MILLISECONDS)
.writeTimeout(0, TimeUnit.MILLISECONDS).cookieJar(new ReactCookieJarContainer());
return OkHttpClientProvider.enableTls12OnPreLollipop(client).build();
}
}
package com.test;
import android.app.Application;
import android.content.Context;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.soloader.SoLoader;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import android.os.Build;
import com.test.CustomClientFactory; // replace <app-name>
import com.facebook.react.modules.network.OkHttpClientProvider;
import okhttp3.OkHttpClient;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost =
new ReactNativeHost(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());
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
OkHttpClientProvider.setOkHttpClientFactory(new CustomClientFactory());
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
/**
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
*
* @param context
* @param reactInstanceManager
*/
private static void initializeFlipper(
Context context, ReactInstanceManager reactInstanceManager) {
if (BuildConfig.DEBUG) {
try {
/*
We use reflection here to pick up the class that initializes Flipper,
since Flipper library is not available in release mode
*/
Class<?> aClass = Class.forName("com.test.ReactNativeFlipper");
aClass
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
.invoke(null, context, reactInstanceManager);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
【问题讨论】:
-
你找到解决方案了吗?
-
很遗憾没有,所以我使用 react-native-fetch-pinch-new 并将服务器证书放入我的项目中
-
react-native-pinch-new。谢谢。
标签: android react-native https axios fetch