一句话区分如何使用encodeURI/decodeURI、encodeURIComponent/decodeURIComponent的实践笔记

1,267 阅读2分钟

一句话区分如何使用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