刚才做公司 passport 项目的时候, 登录界面, 有个重置密码的功能, 跳转到重置密码页, 而重置密码后, 还要调回原有的登录页
当然可以用 history.back, 但为了保证 Url 可复制, 使用代码
登录页的 url 大致是这样的:
http://passport.xxx.com/login?retUrl=http://www.xxx.com/auth/finish?r=http%3A%2F%2Fnews.xxx.com%2Fa%2F272.html
可以看到参数 retUrl 的值非常复杂, 它其实是:
encodeURIComponent('http://www.xxx.com/auth/finish?r=' + encodeURIComponent('http://news.xxx.com/a/272.html'))
的结果, 本来已经过两次 encodeURIComponent 调用了, 如果再来一次, 应该也能达到目的, 但最后出了一点小问题, 可能是多次 encodeURIComponent 导致的
不用纠结, 换一种思路, 将它转换成 base64, 传给重置密码页, 然后在重置密码页解析这个 base64
想法很 nice, 但我一查, 原来 base64 编码, 包含以下字符:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
看看最后的三个字符 +/=, 都是 Url 敏感字符, 所以:
base64 字符串不可直接作为 Url 参数值, 仍需 encodeURIComponent
所以, 最终的方案改为:
- // 在登录页编码
- const retUrl = encodeURIComponent(btoa(location.href))
- const resetPwdUrl = `/auth/resetPwd?retUrl=${retUrl}`
- // 在重置密码页, 获取 retUrl
- // 假设 rawRetUrl 为参数 retUrl 的原始值
- const retUrl = rawRetUrl ? atob(decodeURIComponent(rawRetUrl)) : '/'
btoa 用于将原始数据编码成 base64 字符串, atob 用于解码
浏览器支持情况: IE10 + 所有现代浏览器
来源: http://www.jianshu.com/p/96d9f68a1733