URL 不能直接包含中文等非 ASCII 字符。若把整条 URL 或已编码的参数再次编码,也会破坏 : / ? & = 等结构字符或产生双重编码。
问题描述
在 Cocos2d-x 中使用 cc.Application:getInstance():openURL(url) 打开链接前,应确保查询参数已经合法编码:
1 2 3 4 5
| // 包含中文,iOS无法打开 https://www.baidu.com/s?wd=你好
// 将 '你好' 转换成 '%E4%BD%A0%E5%A5%BD',即可在iOS上打开 https://www.baidu.com/s?wd=%E4%BD%A0%E5%A5%BD
|
URL 编码与解码
Lua 字符串按 UTF-8 字节处理,下面的编码函数会逐字节生成百分号编码。空格使用 %20,不把 + 当作通用空格替代:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| local function encodeUrl(s) s = tostring(s or "") return (string.gsub(s, "([^%w%-%._~])", function(c) return string.format("%%%02X", string.byte(c)) end)) end
local function decodeUrl(s) s = tostring(s or ""):gsub("%+", " ") return (s:gsub("%%(%x%x)", function(h) return string.char(tonumber(h, 16)) end)) end
|
组装查询参数
不要先拼接完整 URL 再整体编码;应只编码参数键和值。下例只处理一个参数,多个参数按相同方式分别编码:
1 2 3 4
| local keyword = "你好" local url = "https://www.baidu.com/s?wd=" .. encodeUrl(keyword)
cc.Application:getInstance():openURL(url)
|
对于已有 URL,必须先明确哪些参数已经编码。无法判断来源时,不要盲目进行第二次编码;优先在生成参数的业务边界统一完成编码。
相关阅读