一句话区分如何使用encodeURI/decodeURI、encodeURIComponent/decodeURIComponent的实践笔记
上次工作中遇到一个场景:传参是一个完成的URL,而直接把URL传过去明显是行不通的,因为URL上有一些字符是有特殊意义的,而且也有可能url会存在中文等情况,会变得非常不可控,所以URL需要字符编码处理,再进行传参。 之前没有细想,但是为了加深理解、记忆,我把这方面也写下来。
问题场景
访问链接 https://www.xiaoyexiang.com/oauth2/authorize?redirect_uri={url}
,{url}
是一个链接参数。应为https://api.xiaoyexiang.com/api/weixin/login/oauth2?next=https://www.xiaoyexiang.com/classroom/home
刚开始我是使用了 encodeURI()
来处理URL,发现并没有什么效果:
let loginUrl = 'https://www.xiaoyexiang.com/oauth2/authorize?redirect_uri={redirect_uri}';
const originUri = `https://api.xiaoyexiang.com/api/weixin/login/oauth2?next=https://wwww.xiaoyexiang.com/l/s/352?_source=index_rcmd`;
const encodedUrl = encodeURI(originUri);
loginUrl = loginUrl.replace('{redirect_uri}', encodedUrl);
console.log(loginUrl);
// https://www.xiaoyexiang.com/oauth2/authorize?redirect_uri=https://api.xiaoyexiang.com/api/weixin/login/oauth2?next=https://wwww.xiaoyexiang.com/l/s/352?_source=index_rcmd
console.log(encodedUrl);
// https://api.xiaoyexiang.com/api/weixin/login/oauth2?next=https://wwww.xiaoyexiang.com/l/s/352?_source=index_rcmd
后来查阅资料改用 encodeURIComponent()
:
let loginUrl = 'https://www.xiaoyexiang.com/oauth2/authorize?redirect_uri={redirect_uri}';
const originUri = `https://api.xiaoyexiang.com/api/weixin/login/oauth2?next=https://wwww.xiaoyexiang.com/l/s/352?_source=index_rcmd`;
const encodedUrl = encodeURIComponent(originUri);
loginUrl = loginUrl.replace('{redirect_uri}', encodedUrl);
console.log(loginUrl);
// https://www.xiaoyexiang.com/oauth2/authorize?redirect_uri=https%3A%2F%2Fapi.xiaoyexiang.com%2Fapi%2Fweixin%2Flogin%2Foauth2%3Fnext%3Dhttps%3A%2F%2Fwwww.xiaoyexiang.com%2Fl%2Fs%2F352%3F_source%3Dindex_rcmd
console.log(encodedUrl);
// https%3A%2F%2Fapi.xiaoyexiang.com%2Fapi%2Fweixin%2Flogin%2Foauth2%3Fnext%3Dhttps%3A%2F%2Fwwww.xiaoyexiang.com%2Fl%2Fs%2F352%3F_source%3Dindex_rcmd
问题解释
encodeURI/decodeURI、encodeURIComponent/decodeURIComponent 这四个方法的用处
都是用来编码和解码URI的。
encodedURI
- 函数通过将特定字符的每个实例替换为一个、两个、三或四转义序列来对统一资源标识符 (URI) 进行编码 (该字符的 UTF-8 编码仅为四转义序列)由两个 "代理" 字符组成)。
- encodeURI 自身无法产生能适用于HTTP GET 或 POST 请求的URI,例如对于 XMLHTTPRequests, 因为 "&", "+", 和 "=" 不会被编码,然而在 GET 和 POST 请求中它们是特殊字符。然而encodeURIComponent这个方法会对这些字符编码。
decodeURI
函数解码一个由encodeURI 先前创建的统一资源标识符(URI)或类似的例程。
encodeURIComponent
- 是对统一资源标识符(URI)的组成部分进行编码的方法。它使用一到四个转义序列来表示字符串中的每个字符的UTF-8编码(只有由两个Unicode代理区字符组成的字符才用四个转义字符编码)。
- 转义除了字母、数字、
(
、)
、.
、!
、~
、*
、'
、-
和_
之外的所有
decodeURIComponent
方法用于解码由 encodeURIComponent 方法或者其它类似方法编码的部分统一资源标识符(URI)。
个人总结
当你需要转码/解码的URL是需要一个完整、可直接访问的URL时,应该使用encodeURI/decodeURI; 当你需要转码/解码的URL是作为链接的一部分,比如用作参数的情况,应该使用encodeURIComponent/decodeURIComponent