如何使用Dart的Uri类正确解析参数中包含#符号的链接
问题原因
URL 规范中 # 是*片段标识符(fragment)*的起始标记,优先级高于查询参数:Uri.parse 遇到 # 会直接将后续内容全部识别为片段,不会计入查询参数,因此你原代码中参数 p 的值到 # 就被截断。
解决方案
方案1:构造URL时提前编码参数值(最规范,优先使用)
如果可以控制URL的生成逻辑,对参数值做URL编码后再拼接,即可避免特殊字符截断参数:
// 1. 先编码参数中的特殊字符 String paramValue = '{"url": "https://test.test.com/#/a/b"}'; String encodedParam = Uri.encodeComponent(paramValue); // 2. 拼接生成完整URL String url = 'scheme://a.b.c/d?p=$encodedParam'; // 3. 解析后解码获取原始值 Uri uri = Uri.parse(url); var map = uri.queryParameters; String pOriginalValue = Uri.decodeComponent(map['p']!); print(pOriginalValue); // 输出:{"url": "https://test.test.com/#/a/b"}
方案2:手动处理已有的未编码URL
如果无法修改输入的原始URL,可以先手动替换查询参数范围内的 # 为编码值 %23 后再解析:
String rawUrl = 'scheme://a.b.c/d?p={"url": "https://test.test.com/#/a/b"}'; int queryStartIndex = rawUrl.indexOf('?'); int fragmentStartIndex = rawUrl.indexOf('#'); String processedUrl = rawUrl; // 判断#是否出现在查询参数范围内 if (queryStartIndex != -1 && fragmentStartIndex > queryStartIndex) { String queryPart = rawUrl.substring(0, fragmentStartIndex); String fragmentPart = rawUrl.substring(fragmentStartIndex); // 替换查询参数内的#为编码值 processedUrl = queryPart.replaceAll('#', '%23') + fragmentPart; } Uri uri = Uri.parse(processedUrl); var map = uri.queryParameters; print(map['p']); // 输出:{"url": "https://test.test.com/#/a/b"}
内容的提问来源于stack exchange,提问作者Liu Silong
相关产品推荐
相关产品推荐

