You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter调用Node.js后端实现用户注册登录时出现HandshakeException错误求助

解决Flutter POST请求触发HandshakeException: WRONG_VERSION_NUMBER的问题

这个错误我之前帮不少开发者排查过,结合你说的「Postman测试正常但Flutter客户端报错」的情况,大概率是TLS版本不兼容或者HTTP/HTTPS协议不匹配导致的,下面是几个靠谱的排查和解决方向:

1. 先检查请求URL的协议是否搞反了

这是最常见的坑!比如你的Node.js后端明明是用HTTP启动的(比如用http.createServer()),但Flutter里写的请求URL却是https://xxx,反过来也会触发这个错误。

  • 先确认后端的启动方式:看代码里是http还是https模块创建的服务器;
  • 再核对Flutter里的请求地址,本地测试的话,HTTP服务就写http://localhost:xxxx/xxx,HTTPS就写https://开头的地址。

2. 强制Flutter兼容后端的TLS版本

如果后端用了较旧的TLS版本(比如TLS 1.0/1.1),而Flutter默认禁用了这些安全性较低的旧版本,就会出现版本不匹配的报错。你可以针对性地配置Flutter允许兼容的版本:

Android端配置

  1. 在android/app/src/main/res/xml目录下创建network_security_config.xml文件(没有这个目录就新建),内容如下:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">你的后端域名/IP地址</domain>
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </domain-config>
</network-security-config>
  1. 打开android/app/src/main/AndroidManifest.xml,在<application>标签里添加这个配置:
android:networkSecurityConfig="@xml/network_security_config"

iOS端配置

打开ios/Runner/Info.plist,添加以下配置(可以选择宽松模式或者只允许特定域名的严格模式):

<key>NSAppTransportSecurity</key>
<dict>
    <!-- 宽松模式:允许所有请求,适合开发测试 -->
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    
    <!-- 严格模式:只允许指定域名,生产环境推荐用这个 -->
    <!--
    <key>NSExceptionDomains</key>
    <dict>
        <key>你的后端域名</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSTemporaryExceptionMinimumTLSVersion</key>
            <string>TLSv1.0</string>
        </dict>
    </dict>
    -->
</dict>

3. 调整Node.js后端的TLS配置

如果后端是HTTPS服务,那要确保它的TLS版本范围和Flutter兼容。Flutter默认支持TLS 1.2及以上版本,你可以在Node.js的HTTPS服务器配置里明确指定:

const https = require('https');
const fs = require('fs');

const serverOptions = {
  key: fs.readFileSync('./private-key.pem'), // 你的私钥文件
  cert: fs.readFileSync('./certificate.pem'), // 你的证书文件
  minVersion: 'TLSv1.2', // 最低兼容TLS 1.2
  maxVersion: 'TLSv1.3' // 最高支持TLS 1.3
};

https.createServer(serverOptions, (req, res) => {
  // 你的后端业务逻辑
}).listen(443);

4. 本地测试临时禁用证书验证(仅限开发环境!)

如果是本地跑HTTPS服务测试,Flutter可能会因为自签名证书的问题触发握手错误。这时候可以临时禁用证书验证(生产环境绝对不能这么做,会有安全风险):
比如用http包的话,可以这么写:

import 'dart:io';
import 'package:http/http.dart' as http;

Future<void> sendRegisterRequest() async {
  // 创建忽略证书验证的HttpClient
  HttpClient httpClient = HttpClient()
    ..badCertificateCallback = (X509Certificate cert, String host, int port) => true;
  http.IOClient ioClient = http.IOClient(httpClient);

  try {
    final response = await ioClient.post(
      Uri.parse('https://localhost:3000/api/register'),
      body: {'username': 'test_user', 'password': 'test_pass'},
    );
    print('请求结果: ${response.body}');
  } catch (e) {
    print('请求出错: $e');
  } finally {
    ioClient.close();
  }
}

内容的提问来源于stack exchange,提问作者Nima Javanmardi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 14:04:11