query
的拼接,=
后的字符串必须 encode
encodeURI()
函数通过将特定字符的每个实例替换为一个、两个、三或四转义序列来对统一资源标识符 (URI
) 进行编码 (该字符的UTF-8
编码仅为四转义序列)由两个 “代理” 字符组成)。
encodeURIComponent()
函数通过将一个,两个,三个或四个表示字符的UTF-8
编码的转义序列替换某些字符的每个实例来编码URI
(对于由两个“代理”字符组成的字符而言,将仅是四个转义序列) 。
> var url = "http://localhost:8080/pro?a=1&b=张三&ie=utf-16&c=aaa #index.html";
> var url2 = encodeURI(url)
"http://localhost:8080/pro?a=1&b=张三&ie=utf-16&c=aaa%20#index.html"
> var url3 = encodeURIComponent(url)
"http%3A%2F%2Flocalhost%3A8080%2Fpro%3Fa%3D1%26b%3D%E5%BC%A0%E4%B8%89%26ie%3Dutf-16%26c%3Daaa%20%23index.html"
从上面的例子,可以看出:
encodeURI()
编码后的结果是:空格被替换成了%20
,除了空格之外的任何字符都没有改变;
encodeURIComponent()
则是将所有非字母数字字符替换成对应编码。
encodeURI()
可以对整个URI
进行使用,而encodeURIComponent()
只适用于对附加URI
后面的字符串使用。
所以一般来说,我们使用更多的的是encodeURIComponent()
,因为我们更需要对查询字符串进行编码,而不是整个URI
encodeURI()
用于整个url
跳转,比如:
转化前:location.href = "http://localhost:8080/pro?a=1&b=张三&ie=utf-16&c=aaa #index.html"
;
转化后:location.href = "http://localhost:8080/pro?a=1&b=张三&ie=utf-16&c=aaa%20#index.html"
本例中只是将中文转成%...
,传过去再解码就可以拿到中文
encodeURIComponent()
用于参数的传递,参数包含特殊字符可能会造成间断。比如:
var paramUrl = "http://localhost:8080/aa?a=1&b=2&c=3"
;
var url = "http://localhost:8080/pp?a=1&b="+ paramUrl
;
应该使用encodeURIComponent()
进行转码,
结果:http://localhost:8080/pp?a=1&b=http%3A%2F%2Flocalhost%3A8080%2Faa%3Fa%3D1%26b%3D2%23%26c%3D3
query
的解析,=
后的字符串应该 decode
decodeURI()
函数能解码由encodeURI
创建或其它流程得到的统一资源标识符(URI
)。
decodeURIComponent()
方法用于解码由encodeURIComponent
方法或者其它类似方法编码的部分统一资源标识符(URI
)。
var uri = 'https://www.baidu.com/s?ie=utf-16&word=hello%20%24#index.html';
decodeURI(uri) //https://www.baidu.com/s?ie=utf-16&word=hello %24#index.html
decodeURIComponent(uri) //https://www.baidu.com/s?ie=utf-16&word=hello $#index.html
因为
uri
中有编码值%20
,%24
,decodeURI
只可以把%20
转化为空格,不会对%24
仅从任何处理,因为%24
表示$
符号,$
符号不是使用encodeURI
替换的。
而decodeURIComponent
可以解释任何特殊字符的编码。
// 目标地址
var url = 'https://jf3-shop-test.wanyol.com/activityHtml/sms_redirect.html?a=1&b=张三&ie=utf-16&word=hello #index.html'
url
拼接时,没有做 encode
,url
解析时做了 decode
url
拼接没做encode
,则
>var url = 'https://jf3-shop-test.wanyol.com/activityHtml/sms_redirect.html?a=1&b=张三&ie=utf-16&word=hello #index.html'
url
解析时做了decode
>var url1 = decodeURIComponent(url)
"https://jf3-shop-test.wanyol.com/activityHtml/sms_redirect.html?a=1&b=张三&ie=utf-16&word=hello #index.html"
所以,这个是正常跳转
的
> `https://host1/path1?url=https://host2/path2?key1=val1&key2=val2`
> // 例如
> var url = 'https://www.baidu.com?url=https://jf3-shop-test.wanyol.com/activityHtml/sms_redirect.html?a=1&b=张三&ie=utf-16&word=hello #index.html'
试问 key2=val2
是 host1
链接的参数,还是 host2
链接的参数?具体点
> url
"https://www.baidu.com?url=https://jf3-shop-test.wanyol.com/activityHtml/sms_redirect.html?a=1&b=张三&ie=utf-16&word=hello #index.html"
> function getQuery(name, url) {
... //参数:变量名,url为空则表从当前页面的url中取
... var u = arguments[1] || window.location.search,
... reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"),
... r = u.substr(u.indexOf("\?") + 1).match(reg);
... return r !== null ? r[2] : "";
...}
> getQuery("word",url3)
"hello #index.html"
> var getUrl = getQuery("url",url3)
"https://jf3-shop-test.wanyol.com/activityHtml/sms_redirect.html?a=1"
> decodeURIComponent(getUrl)
"https://jf3-shop-test.wanyol.com/activityHtml/sms_redirect.html?a=1"
明显与我们目标地址不符
,就出错了
url
拼接时,没有做encode
,url
解析时也没有做decode
url
拼接没做encode
,则
> var url = 'https://jf3-shop-test.wanyol.com/activityHtml/sms_redirect.html?a=1&b=张三&ie=utf-16&word=hello #index.html'
url
解析时没做decode
>var url2 = url
"https://jf3-shop-test.wanyol.com/activityHtml/sms_redirect.html?a=1&b=张三&ie=utf-16&word=hello #index.html"
所以,肯定是正常跳转
的
> url
"https://www.baidu.com?url=https://jf3-shop-test.wanyol.com/activityHtml/sms_redirect.html?a=1&b=张三&ie=utf-16&word=hello #index.html"
> getQuery("word",url3)
"hello #index.html"
> var getUrl = getQuery("url",url3)
"https://jf3-shop-test.wanyol.com/activityHtml/sms_redirect.html?a=1"
> getUrl
"https://jf3-shop-test.wanyol.com/activityHtml/sms_redirect.html?a=1"
明显与我们目标地址不符
,就出错了
url
拼接时,做了 encode
,url
解析时没有做 decode
url
拼接做了 encode
,则
> var url = 'https://jf3-shop-test.wanyol.com/activityHtml/sms_redirect.html?a=1&b=张三&ie=utf-16&word=hello #index.html'
> var url2 = "https://www.baidu.com"
> var encodeUrl = encodeURIComponent(url)
"https%3A%2F%2Fjf3-shop-test.wanyol.com%2FactivityHtml%2Fsms_redirect.html%3Fa%3D1%26b%3D%E5%BC%A0%E4%B8%89%26ie%3Dutf-16%26word%3Dhello%20%23index.html" // location.href不能正常跳转的
> var url3 = url2 + "?url=" + encodeUrl
'https://www.baidu.com?url=https%3A%2F%2Fjf3-shop-test.wanyol.com%2FactivityHtml%2Fsms_redirect.html%3Fa%3D1%26b%3D%E5%BC%A0%E4%B8%89%26ie%3Dutf-16%26word%3Dhello%20%23index.html'
url
解析时没做decode
> var getUrl = getQuery("url",url3)
"https%3A%2F%2Fjf3-shop-test.wanyol.com%2FactivityHtml%2Fsms_redirect.html%3Fa%3D1%26b%3D%E5%BC%A0%E4%B8%89%26ie%3Dutf-16%26word%3Dhello%20%23index.html" // location.href不能正常跳转的
所以,肯定是不能正常跳转
的
url
拼接时,做了 encode
,url
解析时做了decode
url
拼接做了encode
,则
> var url = 'https://jf3-shop-test.wanyol.com/activityHtml/sms_redirect.html?a=1&b=张三&ie=utf-16&word=hello #index.html'
> var url2 = "https://www.baidu.com"
> var encodeUrl = encodeURIComponent(url)
"https%3A%2F%2Fjf3-shop-test.wanyol.com%2FactivityHtml%2Fsms_redirect.html%3Fa%3D1%26b%3D%E5%BC%A0%E4%B8%89%26ie%3Dutf-16%26word%3Dhello%20%23index.html" // location.href不能正常跳转的
> var url3 = url2 + "?url=" + encodeUrl
'https://www.baidu.com?url=https%3A%2F%2Fjf3-shop-test.wanyol.com%2FactivityHtml%2Fsms_redirect.html%3Fa%3D1%26b%3D%E5%BC%A0%E4%B8%89%26ie%3Dutf-16%26word%3Dhello%20%23index.html'
url
解析时做了decode
> var getUrl = getQuery("url",url3)
"https%3A%2F%2Fjf3-shop-test.wanyol.com%2FactivityHtml%2Fsms_redirect.html%3Fa%3D1%26b%3D%E5%BC%A0%E4%B8%89%26ie%3Dutf-16%26word%3Dhello%20%23index.html"
> var url22 = decodeURIComponent(getUrl)
"https://jf3-shop-test.wanyol.com/activityHtml/sms_redirect.html?a=1&b=张三&ie=utf-16&word=hello #index.html"
所以,肯定是正常跳转
的
encodeURIComponent
使用2次从使用上看来,
javascript
使用encodeURIComponent
编码一次,如果是作为Url
请求发送,浏览器是自动会作一次解码,编码方式为浏览器默认。这样在一次编码后,请求到后台后,比如中文就成为乱码了。中间即使编码方式是一致也会乱码。解决方法是在前台javascript
使用encodeURIComponent
两次,这样浏览器解码一次后,还是一种编码后的字符,传递到后台就不会是乱码,当然你得在后台做一次解码工作。
// 比如你把一个请求:
> `http://localhost:8080/sxkj/news/actionNewsByCategoryId.do?categoryId=3&categoryName=%E4%BA%BA%E6%89%8D%E6%8B%9B%E8%81%98`
// 浏览器是自动把我categoryName后面的给解码为了中文“人才招聘”,请求到了后台是乱码,而把categoryName后面“%E4%BA%BA%E6%89%8D%E6%8B%9B%E8%81%98”,再次编码,作为参数请求后台,后台拿到的就是正确的中文字符了。
> decodeURIComponent('%E4%BA%BA%E6%89%8D%E6%8B%9B%E8%81%98')
'人才招聘'
所以对
param
不encode
很容易出现问题,上面的demo
我们解析之后的getUrl
,与我们的目标url
,看着差不多,但丢失参数及信息,说明了url
的param
必须encode
,如果解析的时候,我们不decode
,是不能正常实现跳转的 ,所以我们也阔以通过encode
和decode
验证我们的准确性,encode
和decode
规范也显得至关重要了。