面试题答案
一键面试1. 添加依赖
在 pubspec.yaml
文件中添加 http
或 dio
依赖,以发起网络请求。例如,添加 http
依赖:
dependencies:
http: ^0.13.4
如果选择 dio
,添加如下依赖:
dependencies:
dio: ^4.0.6
然后运行 flutter pub get
下载依赖。
2. 证书处理
安卓平台
- 信任系统证书:默认情况下,Flutter 安卓应用会信任系统证书,因此如果请求的服务器使用的是受信任的 CA 颁发的证书,无需额外配置证书。
- 使用自定义证书:
- 将证书文件(例如
your_cert.crt
)放到android/app/src/main/res/raw
目录下(如果没有raw
目录,需手动创建)。 - 在
android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java
文件中添加如下代码:
- 将证书文件(例如
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.PluginRegistry;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import io.flutter.plugins.http.HttpPlugin;
public class GeneratedPluginRegistrant {
public static void registerWith(PluginRegistry registry) {
if (alreadyRegisteredWith(registry)) {
return;
}
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = registry.context().getResources().openRawResource(R.raw.your_cert);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
} finally {
caInput.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
httpClientBuilder.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) tmf.getTrustManagers()[0]);
httpClientBuilder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
HttpPlugin.registerWith(registry.registrarFor("io.flutter.plugins.http.HttpPlugin"), httpClientBuilder.build());
}
private static boolean alreadyRegisteredWith(PluginRegistry registry) {
final String key = GeneratedPluginRegistrant.class.getCanonicalName();
if (registry.hasPlugin(key)) {
return true;
}
registry.registrarFor(key);
return false;
}
}
iOS平台
- 信任系统证书:与安卓类似,默认情况下,Flutter iOS 应用会信任系统证书。
- 使用自定义证书:
- 将证书文件(例如
your_cert.cer
)添加到ios/Runner
项目中,并确保其Target Membership
勾选了Runner
。 - 在
ios/Runner/Info.plist
文件中添加如下配置:
- 将证书文件(例如
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
<key>NSExceptionDomains</key>
<dict>
<key>your_domain.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<false/>
<key>NSExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSRequiresCertificateTransparency</key>
<false/>
<key>NSIdentityConstraints</key>
<dict>
<key>NSCertificateTransparencyPublicKeyHashes</key>
<array>
<string>YOUR_CERTIFICATE_HASH</string>
</array>
</dict>
</dict>
</dict>
</dict>
要获取证书哈希,可以使用以下命令(在 macOS 上):
openssl x509 -noout -in your_cert.cer -pubkey | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
3. 发起HTTPS请求
使用 http
库
import 'package:http/http.dart' as http;
Future<void> fetchData() async {
final response = await http.get(Uri.parse('https://your_domain.com/api/data'));
if (response.statusCode == 200) {
print(response.body);
} else {
print('Request failed with status: ${response.statusCode}.');
}
}
使用 dio
库
import 'package:dio/dio.dart';
Future<void> fetchData() async {
Dio dio = Dio();
try {
Response response = await dio.get('https://your_domain.com/api/data');
print(response.data);
} catch (e) {
print('Error: $e');
}
}