URL 中的空格、加号究竟应该使用何种方式编码
来自公众号:Gopher指北
URL 中不能显示地包含空格这已经是一个共识,而空格以何种形式存在,在不同的标准中又不完全一致,以致于不同的语言也有了不同的实现。
rfc2396
中明确表示空格应该被编码为%20
。
而 W3C 的标准中却又说空格可以被替换为+
或者%20
。
老许当场懵逼,空格被替换为+
,那+
本身只能被编码。既然如此,为什么不直接对空格进行编码呢。当然这只是老许心中的疑惑,以前的背景我们已经无法追溯,已成的事实我们也无法改变。但,空格到底是被替换为+
还是20%
,+
是否需要被编码都是现在的我们需要直面的问题。
Go 常用的三种 URL 编码方式
作为 Gopher 最先关注的自然是 Go 语言本身的实现,因此我们首先了解一下 Go 中常用的三种 URL 编码方式的异同。
url.QueryEscape
使用url.QueryEscape
编码时,空格被编码为+
,而+
本身被编码为%2B
。
url.PathEscape
使用url.PathEscape
编码时,空格被编码为20%
, 而+
则未被编码。
url.Values
使用(Values).Encode
方法编码时,空格被编码为+
,而+
本身被编码为%2B
,进一步查看(Values).Encode
方法的源码知其内部仍旧调用url.QueryEscape
函数。而(Values).Encode
方法和url.QueryEscape
的区别在于前者仅编码 query 中的 key 和 value,后者会对=
、&
均进行编码。
对我们开发者而言,这三种编码方式到底应该使用哪一种,请继续阅读后文相信你可以在后面的文章中找到答案。
不同语言中的实现
既然空格和+
在 Go 中的 URL 编码方式有不同的实现,那在其他语言中是否也存在这样的情况呢,下面以 PHP 和 JS 为例。
PHP 中的 URL 编码
urlencode
rawurlencode
PHP 的urlencode
和 Go 的url.QueryEscape
函数效果一致,而rawurlencode
则将空格和+
均进行编码。
JS 中的 URL 编码
encodeURI
encodeURIComponent
JS 的encodeURI
和 Go 的url.PathEscape
函数效果一致,而encodeURIComponent
则将空格和+
均进行编码。
我们应该怎么做
更推荐使用 url.PathEscape 函数编码
在前文中已经总结了Go
、PHP
和JS
对 +Gopher指北
的编码操作,下面总结一下其对应的解码操作是否可行的二维表。
上表中的YY
和Y
同含义,老许仅以YY
表示在 Go 中推荐使用url.PathEscape
进行编码,同时在 PHP 和 JS 中分别推荐使用rawurldecode
和decodeURIComponent
进行解码。
在实际的开发过程中,Gopher 一定会存在需要解码的场景,此时就需要和 URL 编码方进行沟通以得到合适的方式解码。
对值进行编码
那有没有通用的不需要 URL 编解码的方式呢?毫无疑问是有的!以base32
编码为例,其编码字符集为A-Z和数字2-7
,此时对值进行 base32 编码后就无需 url 编码了。
最后,衷心希望本文能够对各位读者有一定的帮助。
本文使用环境分别为
PHP 7.3.29
、go 1.16.6
和js Chrome94.0.4606.71的Console
参考
https://www.rfc-editor.org/rfc/rfc2396.txt
https://www.w3schools.com/tags/ref_urlencode.ASP
版权声明: 本文为 InfoQ 作者【Gopher指北】的原创文章。
原文链接:【http://xie.infoq.cn/article/e7aeb518f5171fda7b8d351ad】。未经作者许可,禁止转载。
评论