fix: 适配多平台url编码规则,修复双重编码问题
针对H5和小程序/App平台分别处理url参数编码: 1. H5平台需要手动encodeURIComponent避免参数解析错误 2. 小程序/App平台由uni内部自动编码,避免双重编码导致参数解码异常 同时重构了工具类中的编码逻辑,统一多场景下的平台适配规则
This commit is contained in:
@@ -282,7 +282,14 @@ export const resolvePageUrl = (page_key, params = {}) => {
|
|||||||
Object.keys(params).forEach(function (key) {
|
Object.keys(params).forEach(function (key) {
|
||||||
const value = params[key];
|
const value = params[key];
|
||||||
if (value === null || value === undefined || value === '') return;
|
if (value === null || value === undefined || value === '') return;
|
||||||
|
// H5:浏览器不自动编码,需要手动 encodeURIComponent
|
||||||
|
// 小程序/App:uni.navigateTo 会自动编码,这里不能再 encode,否则双重编码
|
||||||
|
// #ifdef H5
|
||||||
parts.push(key + '=' + encodeURIComponent(value));
|
parts.push(key + '=' + encodeURIComponent(value));
|
||||||
|
// #endif
|
||||||
|
// #ifndef H5
|
||||||
|
parts.push(key + '=' + value);
|
||||||
|
// #endif
|
||||||
});
|
});
|
||||||
if (parts.length > 0) {
|
if (parts.length > 0) {
|
||||||
url = url + (url.indexOf('?') !== -1 ? '&' : '?') + parts.join('&');
|
url = url + (url.indexOf('?') !== -1 ? '&' : '?') + parts.join('&');
|
||||||
@@ -643,18 +650,25 @@ export default {
|
|||||||
// 2. 合并 param:同 key 时新值覆盖旧值,杜绝 ?name=A&name=B 这种重复
|
// 2. 合并 param:同 key 时新值覆盖旧值,杜绝 ?name=A&name=B 这种重复
|
||||||
const merged = Object.assign({}, existingParams, param || {});
|
const merged = Object.assign({}, existingParams, param || {});
|
||||||
|
|
||||||
// 3. 统一编码。decode -> encode 双向 roundtrip 兼具两种语义:
|
// 3. 参数编码策略,按平台区分:
|
||||||
// - 调用方传原始值(/pages_tool/index/diy?name=XXX) -> encode 后 %2F%3F...
|
// - 小程序/App: uni.navigateTo / router.pushUrl 内部会自动对 url 做一次编码,
|
||||||
// - 调用方已传编码值(%2F%3F...) -> decode 还原 -> encode 还原回去,不会被二次编码
|
// 若在 JS 侧再 encodeURIComponent 一次,会被平台再编码一层,目标页 onLoad(options)
|
||||||
// - 任何不能 decode 的非法序列(如裸 %) 走 catch 路径,直接 encode
|
// 只 decode 一次后仍是编码形态(如 %25E6%25B2%2599%25E5%258F%2591 -> %E6%B2%99%E5%8F%91)
|
||||||
|
// => 这里必须保持原始值,完全交给平台去编码
|
||||||
|
// - H5: 浏览器不会自动编码 url,若参数含 & ? = 等特殊字符会被 queryString 错位解析
|
||||||
|
// => 这里仍需手动 encodeURIComponent,decode->encode roundtrip 兼容调用方已编码的入参
|
||||||
const safeEncode = (v) => {
|
const safeEncode = (v) => {
|
||||||
const s = v == null ? '' : String(v);
|
const s = v == null ? '' : String(v);
|
||||||
// try {
|
// #ifdef H5
|
||||||
// return encodeURIComponent(decodeURIComponent(s));
|
try {
|
||||||
// } catch (e) {
|
return encodeURIComponent(decodeURIComponent(s));
|
||||||
// return encodeURIComponent(s);
|
} catch (e) {
|
||||||
// }
|
return encodeURIComponent(s);
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
// #ifndef H5
|
||||||
return s;
|
return s;
|
||||||
|
// #endif
|
||||||
};
|
};
|
||||||
const queryStr = Object.keys(merged)
|
const queryStr = Object.keys(merged)
|
||||||
.map(k => safeEncode(k) + '=' + safeEncode(merged[k]))
|
.map(k => safeEncode(k) + '=' + safeEncode(merged[k]))
|
||||||
@@ -2020,10 +2034,12 @@ export default {
|
|||||||
// 判断当前 URL 是否已经包含查询参数,决定使用 ? 还是 &
|
// 判断当前 URL 是否已经包含查询参数,决定使用 ? 还是 &
|
||||||
const separator = targetUrl.includes('?') ? '&' : '?';
|
const separator = targetUrl.includes('?') ? '&' : '?';
|
||||||
|
|
||||||
// 遍历参数对象,手动进行 encodeURIComponent 编码并拼接
|
// 遍历参数对象,拼接参数
|
||||||
|
// 小程序/App 端:uni.navigateTo/router.pushUrl 内部会自动对 url 编码,
|
||||||
|
// 这里不能再 encodeURIComponent,否则会被平台再编码一层导致双重编码
|
||||||
const queryString = Object.entries(params)
|
const queryString = Object.entries(params)
|
||||||
.filter(([_, value]) => value !== undefined && value !== null)
|
.filter(([_, value]) => value !== undefined && value !== null)
|
||||||
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
|
.map(([key, value]) => `${key}=${value}`)
|
||||||
.join('&');
|
.join('&');
|
||||||
|
|
||||||
// 重新拼接成完整的 URL
|
// 重新拼接成完整的 URL
|
||||||
|
|||||||
@@ -50,9 +50,18 @@ export default {
|
|||||||
helpDetail(e) {
|
helpDetail(e) {
|
||||||
// #ifndef MP-WEIXIN
|
// #ifndef MP-WEIXIN
|
||||||
if (e.link_address) {
|
if (e.link_address) {
|
||||||
|
// H5:浏览器不自动编码,需要手动 encodeURIComponent
|
||||||
|
// 其他小程序平台(HarmonyOS 等):uni.redirectTo 内部会自动编码,不能再 encode,否则双重编码
|
||||||
|
// #ifdef H5
|
||||||
uni.redirectTo({
|
uni.redirectTo({
|
||||||
url: '/pages_tool/webview/webview?src=' + encodeURIComponent(e.link_address)
|
url: '/pages_tool/webview/webview?src=' + encodeURIComponent(e.link_address)
|
||||||
});
|
});
|
||||||
|
// #endif
|
||||||
|
// #ifndef H5
|
||||||
|
uni.redirectTo({
|
||||||
|
url: '/pages_tool/webview/webview?src=' + e.link_address
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
} else {
|
} else {
|
||||||
this.$util.redirectTo('/pages_tool/help/detail', {
|
this.$util.redirectTo('/pages_tool/help/detail', {
|
||||||
id: e.id
|
id: e.id
|
||||||
|
|||||||
Reference in New Issue
Block a user