写点什么

URL 中的空格、加号究竟应该使用何种方式编码

作者:Gopher指北
  • 2022 年 2 月 06 日
  • 本文字数:1400 字

    阅读完需:约 5 分钟

URL中的空格、加号究竟应该使用何种方式编码

来自公众号:Gopher指北


URL 中不能显示地包含空格这已经是一个共识,而空格以何种形式存在,在不同的标准中又不完全一致,以致于不同的语言也有了不同的实现。


rfc2396中明确表示空格应该被编码为%20



而 W3C 的标准中却又说空格可以被替换为+或者%20



老许当场懵逼,空格被替换为+,那+本身只能被编码。既然如此,为什么不直接对空格进行编码呢。当然这只是老许心中的疑惑,以前的背景我们已经无法追溯,已成的事实我们也无法改变。但,空格到底是被替换为+还是20%+是否需要被编码都是现在的我们需要直面的问题。

Go 常用的三种 URL 编码方式

作为 Gopher 最先关注的自然是 Go 语言本身的实现,因此我们首先了解一下 Go 中常用的三种 URL 编码方式的异同。

url.QueryEscape

fmt.Println(url.QueryEscape(" +Gopher指北"))// 输出:+%2BGopher%E6%8C%87%E5%8C%97
复制代码


使用url.QueryEscape编码时,空格被编码为+,而+本身被编码为%2B

url.PathEscape

fmt.Println(url.PathEscape(" +Gopher指北"))// 输出:%20+Gopher%E6%8C%87%E5%8C%97
复制代码


使用url.PathEscape编码时,空格被编码为20%, 而+则未被编码。

url.Values

var query = url.Values{}query.Set("hygz", " +Gopher指北")fmt.Println(query.Encode())// 输出:hygz=+%2BGopher%E6%8C%87%E5%8C%97
复制代码


使用(Values).Encode方法编码时,空格被编码为+,而+本身被编码为%2B,进一步查看(Values).Encode方法的源码知其内部仍旧调用url.QueryEscape函数。而(Values).Encode方法和url.QueryEscape的区别在于前者仅编码 query 中的 key 和 value,后者会对=&均进行编码。


对我们开发者而言,这三种编码方式到底应该使用哪一种,请继续阅读后文相信你可以在后面的文章中找到答案。

不同语言中的实现

既然空格和+在 Go 中的 URL 编码方式有不同的实现,那在其他语言中是否也存在这样的情况呢,下面以 PHP 和 JS 为例。

PHP 中的 URL 编码

urlencode


echo urlencode(' +Gopher指北');// 输出:+%2BGopher%E6%8C%87%E5%8C%97
复制代码


rawurlencode


echo rawurlencode(" +Gopher指北");// 输出:%20%2BGopher%E6%8C%87%E5%8C%97
复制代码


PHP 的urlencode和 Go 的url.QueryEscape函数效果一致,而rawurlencode则将空格和+均进行编码。

JS 中的 URL 编码

encodeURI


encodeURI(' +Gopher指北')// 输出:%20+Gopher%E6%8C%87%E5%8C%97
复制代码


encodeURIComponent


encodeURIComponent(' +Gopher指北')// 输出:%20%2BGopher%E6%8C%87%E5%8C%97
复制代码


JS 的encodeURI和 Go 的url.PathEscape函数效果一致,而encodeURIComponent则将空格和+均进行编码。

我们应该怎么做

更推荐使用 url.PathEscape 函数编码

在前文中已经总结了GoPHPJS +Gopher指北的编码操作,下面总结一下其对应的解码操作是否可行的二维表。



上表中的YYY同含义,老许仅以YY表示在 Go 中推荐使用url.PathEscape进行编码,同时在 PHP 和 JS 中分别推荐使用rawurldecodedecodeURIComponent进行解码。


在实际的开发过程中,Gopher 一定会存在需要解码的场景,此时就需要和 URL 编码方进行沟通以得到合适的方式解码。

对值进行编码

那有没有通用的不需要 URL 编解码的方式呢?毫无疑问是有的!以base32编码为例,其编码字符集为A-Z和数字2-7,此时对值进行 base32 编码后就无需 url 编码了。


最后,衷心希望本文能够对各位读者有一定的帮助。


本文使用环境分别为PHP 7.3.29go 1.16.6js Chrome94.0.4606.71的Console


参考


  • https://www.rfc-editor.org/rfc/rfc2396.txt

  • https://www.w3schools.com/tags/ref_urlencode.ASP

发布于: 刚刚阅读数: 2
用户头像

Gopher指北

关注

还未添加个人签名 2020.09.15 加入

欢迎关注公众号:Gopher指北

评论

发布
暂无评论
URL中的空格、加号究竟应该使用何种方式编码