搜索框里输入「C++ & Java」,拼进地址栏变成 ?kw=C++ & Java,后端只收到 C++,后面的全丢了。问题出在没做 urlencode。
js urlencode 不是某一个函数,而是三个:encodeURI、encodeURIComponent,还有基本没人该用的 escape。用错哪个,参数就断在哪。
整条 URL 用 encodeURI
encodeURI 会保留冒号、斜杠、问号、井号、&、等号这些结构字符,只编码空格、中文和特殊符号。适合把一整条地址丢进去,比如拼回调地址。
encodeURI('https://example.com/a b?x=1&y=2')结果是空格变 %20,问号和 & 原样保留。
参数值用 encodeURIComponent
它连斜杠、问号、&、等号都编码,专门处理参数值。日常写 js urlencode,记住这一条就够:
'?kw=' + encodeURIComponent('C++ & Java')得到 %26、%2B、%20,后端解开后一个字不差。中文按 UTF-8 编码,一个汉字变三个 %XX。
escape 为什么不推荐
escape 是早期浏览器留下的,对非 ASCII 字符会输出 %uXXXX,这种格式服务端解码器多数不认。老代码里见到它,能换就换。
还有一个坑:表单提交 application/x-www-form-urlencoded 时,空格会变成加号。前端用 URLSearchParams 拼参数,它会自动处理编码,比手拼字符串省心。
URLSearchParams 转字符串时,空格会编成加号,和 encodeURIComponent 的 %20 不一样,后端两种都得能解。
解码对应着来
encodeURI 配 decodeURI,encodeURIComponent 配 decodeURIComponent,别交叉用,否则 %2F 会被还原成斜杠,路径就乱了。后端拿到参数一般会自动解一次,前端别重复解。
结论:拼参数值一律 encodeURIComponent,整条地址才用 encodeURI,escape 当它不存在。