Flutter Web运行main前如何获取系统相机扫码的QR码数据
核心逻辑
Android、iOS系统自带相机扫码的跳转逻辑非常直白:识别QR码内的纯文本内容,如果内容是合法URL,直接唤起系统默认浏览器访问该完整URL,QR内写入的所有内容都会完整传递给浏览器,不存在“非Flutter环境扫码丢失附加数据”的问题——你要的经纬度等信息本质上就是URL的一部分,直接从浏览器地址对象里读取即可。
前置要求
生成QR码时不要使用自定义结构化字段存储附加数据,系统相机不会解析这类非URL字段,只会把识别到的纯文本当URL处理。所有需要传递的附加信息直接编码到跳转URL中即可,推荐放在query参数段,示例格式:https://your-web-domain.com/scan-entry?lat=39.9042&lng=116.4074&point_id=10086
如果数据敏感可以先做对称加密再拼接参数,解密逻辑放在Flutter侧即可。
提前读取数据的实现方式
你可以选择两种时机读取数据,都能保证在Flutter应用框架启动、main函数业务逻辑执行前拿到完整QR数据:
方式1:Dart层main函数入口直接读取(最简便)
Dart的main函数是Flutter Web的执行入口,在runApp、Flutter控件绑定初始化之前执行的代码,完全满足提前访问的要求,不需要修改原生web目录文件:
import 'dart:html' as html; import 'package:flutter/material.dart'; // 全局存储QR解析结果,应用内任意位置可直接调用 Map<String, dynamic> qrScanData = {}; void main() { // 此处为Flutter侧最早执行时机,早于所有组件、插件初始化 final fullUrl = html.window.location.href; final uri = Uri.parse(fullUrl); // 解析URL内的附加参数 final lat = double.tryParse(uri.queryParameters['lat'] ?? ''); final lng = double.tryParse(uri.queryParameters['lng'] ?? ''); if (lat != null && lng != null) { qrScanData = { 'lat': lat, 'lng': lng, 'pointId': uri.queryParameters['point_id'], // 其余自定义参数按需解析即可 }; } // 数据读取完成后再初始化Flutter框架、启动应用 WidgetsFlutterBinding.ensureInitialized(); runApp(const MyApp()); }
如果你把附加数据放在URL的hash段、路径段,对应读取uri.fragment、uri.pathSegments属性即可。
方式2:web目录原生JS提前读取(时机最早)
如果需要在Flutter引擎加载前就完成数据解析,可以直接修改项目web/index.html文件,在加载flutter.js脚本之前插入解析逻辑,把数据存在JS全局变量上:
<!-- 在flutter.js加载脚本前插入以下代码 --> <script> window.__QR_SCAN_DATA__ = {}; const urlParams = new URLSearchParams(window.location.search); const lat = parseFloat(urlParams.get('lat')); const lng = parseFloat(urlParams.get('lng')); if (!isNaN(lat) && !isNaN(lng)) { window.__QR_SCAN_DATA__ = { lat: lat, lng: lng, pointId: urlParams.get('point_id') } } </script>
后续Flutter侧通过dart:js_interop读取全局__QR_SCAN_DATA__变量即可,该逻辑执行时机远早于Dart代码运行,完全不存在时序问题。
注意事项
- 系统相机拉起浏览器的URL长度阈值普遍在2000字符以上,普通业务参数、经纬度数据完全可以容纳,不需要担心中间截断。
- URL参数默认都是字符串格式,经纬度等数值类型需要手动做类型转换,避免后续业务逻辑报错。
- 如果需要防参数篡改,可以在生成QR码时给所有参数加签名校验,Flutter侧拿到数据后先验签,不通过直接跳转错误提示页即可。
- 不要在QR码内写入非URL格式的内容,否则系统相机要么不会直接跳转,要么会把内容当搜索词传给搜索引擎,无法正常拉起你的Web应用。
内容的提问来源于stack exchange,提问作者Jure Jureš

