如何解决Vue中URL查询参数传递时的特殊字符转义问题?

新手上路,请多包涵

单点登录操作流程:客户单通过携带值得url路径跳转,白名单界面通过url中得id,key请求后端数据渲染界面。
浏览器URL中输入
http://localhost:8088/taxBureauLogin?id=1206&key=zE9+TICzsrej...

浏览器转义为 http://localhost:8088/taxBureauLoginid=1206&key=zE9%20TICzsre...

前端vue在界面created函数里面获取 key值传给后端,
let searchParams = new URLSearchParams(window.location.search);

但是获取得searchParams得key传给后端拿到后变成了
原字符:zE9+TICzsrejfujj/BXjCQ== 拿到后:zE9 TICzsrejfujj/BXjCQ==

!!!特殊字符被转义 + 变成了空格 ,360浏览器中/ 也被转义,
期望得到浏览器中输入得原格式!大佬们给个招!
不考虑正则因为不确定要传过来有没有空格

image.pngimage.png

阅读 1.5k
4 个回答

后台生成 token 最好是通过 Base64URL 转换一下,避免出现 +/= 这些有特殊含义的字符。

如果后台不想改,那么就算OP和其他回答中说的一样使用 encodeURIComponent 处理获取到的 token 值。如果项目使用的 vue-router3x 版本,那么在打开页面的时候 vue-router 会自动把对应的特殊字符解码了,我们再使用 location API来获取URL信息也是已经转义过的字符串数据了。

OP使用 devTools 输入一下的测试代码测试一下你就明白了:

var testUrl = 'http://localhost:8088/taxBureauLogin?test=123+A'
location.href = testUrl
// 浏览器跳转后开始获取 query 信息
new URLSearchParams(window.location)
// URLSearchParams(13)
//   size: 13
//   <entries>
//     0: href → "http://localhost:8080/taxBureauLogin?id=123&test=123%20A"
//     1: origin → "http://localhost:8080"
//     2: protocol → "http:"
//     3: host → "localhost:8080"
//     4: hostname → "localhost"
//     5: port → "8080"
//     6: pathname → "/taxBureauLogin"
//     7: search → "?id=123&test=123%20A"
//     8: hash → ""
//     9: assign → "function assign()"
//     10: replace → "function replace()"
//     11: reload → "function reload()"
//     12: toString → "function toString()"

如果 vue-router4.x 就不会有这个问题。

$route 属性编码

无论在哪里启动导航,paramsqueryhash 中的解码值现在都是一致的(旧的浏览器仍然会产生未编码的 pathfullPath)。初始导航应产生与应用内部导航相同的结果。

给定任何规范化的路由地址:

  • path, fullPath中的值不再被解码了。例如,直接在地址栏上写 "https://example.com/hello world",将得到编码后的版本:"https://example.com/hello%20world",而 "path" 和 "fullPath" 都是 "/hello%20world"。
  • hash 现在被解码了,这样就可以复制过来。router.push({ hash: $route.hash }) 可以直接用于 scrollBehaviorel 配置中。
  • 当使用 pushresolvereplace 并在对象中提供 string 地址或 path 属性时,必须进行编码(像以前的版本一样)。另一方面,paramsqueryhash 必须以未编码的版本提供。
  • 斜线字符(/)现在已在 params 内正确解码,同时仍在 URL 上产生一个编码版本:%2F

原因:这样,在调用 router.push()router.resolve() 时,可以很容易地复制一个地址的现有属性,并使产生的路由地址在各浏览器之间保持一致。router.push() 现在是幂等的,这意味着调用 router.push(route.fullPath)router.push({ hash: route.hash })router.push({ query: route.query })router.push({ params: route.params }) 不会产生额外的编码。


所以我的建议还是在单点登录生成 token 的时候就把这这些特殊字符处理掉,而不是丢给前端处理。

const u1 = new URL('https://example.com?key=1+1'),
    u2 = new URL('https://exmaple.com?key=1%2b1')

console.log(u1.searchParams.get('key')) // 1 1
console.log(u2.searchParams.get('key')) // 1+1

你遇到的问题是由于 URL 中的特殊字符在传递过程中被转义了。特别是 + 号被转义成了空格。为了避免这种情况,你可以在前端对这些特殊字符进行编码和解码。
在 Vue.js 中,你可以使用 encodeURIComponent 和 decodeURIComponent 来处理这些特殊字符。以下是一个示例:

  1. 编码 URL 参数: 在生成 URL 时,使用 encodeURIComponent 对 key 进行编码。
    JavaScript代码
    let key = "zE9+TICzsrejfujj/BXjCQ==";
    let encodedKey = encodeURIComponent(key);
    let url = http://localhost:8088/taxBureauLogin?id=1206&key=${encodedKey};
  2. 解码 URL 参数: 在 Vue.js 中获取参数时,使用 decodeURIComponent 对 key 进行解码。

JavaScript代码

let searchParams = new URLSearchParams(window.location.search);
let key = searchParams.get('key');
let decodedKey = decodeURIComponent(key);

这样可以确保在传递过程中,特殊字符不会被错误地转义。

推荐问题
宣传栏