我正在尝试使用以下功能从 flutter 发送
https
请求:
Future<void> sendOTP(PhoneNumber phoneNumber) async {
try {
final String url = 'https://127.0.0.1:5432/api/send_otp';
final response = await _dio.post(
url,
data: {'number': 1234567890},
options: Options(
headers: {
'Content-Type': 'application/json',
},
),
);
if (response.statusCode != 200) {
throw Exception("Failed to send OTP: ${response.statusCode}");
}
} on DioError catch (e) {
throw Exception("Failed to send OTP: ${e.error.toString()}");
}
}
要启用
ssl certificate
,我在我的主要方法中添加了以下代码:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
ByteData data = await PlatformAssetBundle().load('asset/certificate/certificate.pem');
SecurityContext.defaultContext
.setTrustedCertificatesBytes(data.buffer.asUint8List());
runApp(const MyApp());
}
我已经从
https://letsencrypt.org/certs/lets-encrypt-r3.pem下载了
certificate.pem
文件。
当我使用
thunderclient
或 postman
和证书发送请求时,它可以工作,但从 flutter 应用程序中它会抛出以下错误:
Error: HandshakeException: Handshake error in client (OS Error:
TLSV1_ALERT_DECODE_ERROR(tls_record.cc:594))
对于服务器,我使用
actix-web
和 rustls
- 如果相关的话。请建议我该如何解决这个问题?
我有类似的问题,经过几个小时的研究我发现:
如您所见,我的 API 是通过 android 模拟器访问的,但如果我使用 Dio Http(版本 5.1.1)运行我的 flutter 代码,它会抛出握手异常。 我尝试了与您使用的完全相同的代码,添加了证书但没有任何改变。我真的不知道从现在开始该怎么办。这真的很令人沮丧,也许我必须使用 Brownser 而不是模拟器来开发我的应用程序。
这是我的 dio 基本选项配置,没问题:
我还尝试在 android 清单中添加互联网权限,但没有任何改变,我还尝试指向我的 API 的 http 版本,但发生了相同的错误。 也许这是 Dio Http 的一个 bug?
经过一番研究,我终于找到了这个问题的解决方案。基本上你必须在创建 Dio 实例时添加以下代码:
class DioSingleton {
static final baseOptions = BaseOptions(
baseUrl: "https://10.0.2.2:7027/api/",
);
static Dio createInstance() {
var dio = Dio(baseOptions);
dio.httpClientAdapter = IOHttpClientAdapter(
onHttpClientCreate: (client) {
client.badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
return client;
},
);
return dio;
}
}
此外,您不需要配置 Android 模拟器来使用代理或任何不同的配置。只需“按原样”使用,一切都会正常。 如果您的计算机上运行着 localhost api,请记住使用地址 10.0.2.2。就我而言,我有一个在本地主机中运行的 .net6 API。 如果这解决了您的问题,请将此标记为接受的答案。
试试这个:
final Dio client;
final Duration _defaultTimeout = const Duration(seconds: 25);
ConfiguredDio({required this.client}) {
client.httpClientAdapter = IOHttpClientAdapter(
createHttpClient: () => HttpClient()..badCertificateCallback = (_, __, ___) => true);