“net/url”无法解析带有井号的URL。

huangapple go评论181阅读模式
英文:

"net/url" can't parse url with pound

问题

我有以下代码。

main.go:

  1. package main
  2. import "fmt"
  3. import "net/url"
  4. func main() {
  5. connString := "postgresql://postgres:password@192.168.1.10:5432/postgres"
  6. parsedUrl, err := url.Parse(connString)
  7. if err != nil {
  8. fmt.Println(err)
  9. }
  10. fmt.Println("=")
  11. fmt.Println(parsedUrl.User)
  12. fmt.Println("=")
  13. }

执行结果:

  1. $ go run main.go
  2. =
  3. postgres:password
  4. =

到目前为止,一切都很好,你可以看到我们成功地将 parsedUrl.User 解析为 postgres:password。问题出现在我将密码更改为包含 password# 的情况下。

  1. connString := "postgresql://postgres:password#@192.168.1.10:5432/postgres"

然后,再次运行代码,输出结果如下:

  1. =
  2. =

你可以看到代码无法获取 postgres:password#。看起来在 HTML 中,# 被视为锚点,这是问题的根本原因吗?

**总结一下,我的问题是:**我该如何修改代码来处理密码中包含 # 的情况?

英文:

I have next code.

main.go:

  1. package main
  2. import "fmt"
  3. import "net/url"
  4. func main() {
  5. connString := "postgresql://postgres:password@192.168.1.10:5432/postgres"
  6. parsedUrl, err := url.Parse(connString)
  7. if err != nil {
  8. fmt.Println(err)
  9. }
  10. fmt.Println("=")
  11. fmt.Println(parsedUrl.User)
  12. fmt.Println("=")
  13. }

Execution:

  1. $ go run main.go
  2. =
  3. postgres:password
  4. =

So far so good, you could see we successfully get parsedUrl.User as postgres:password. Problems happens when I change the password to password# which has a bound in it.

  1. connString := "postgresql://postgres:password#@192.168.1.10:5432/postgres"

Then, run it again, it outputs as next:

  1. =
  2. =

You could see the code can't fetch postgres:password#. It looks # in html would be treat as anchor, is this the root cause?

To sum all, my question is: how I could fix my code to handle the situation which I have # in password?

答案1

得分: 3

是的,#表示一个片段。

解决这个问题的方法是转义#字符:

  1. connString := fmt.Sprintf("postgresql://postgres:password%s@192.168.1.10:5432/postgres", url.PathEscape("#"))
  2. parsedUrl, _ := url.Parse(connString)
  3. fmt.Println(url.PathUnescape(parsedUrl.User.String()))

输出结果为:

  1. postgres:password# <nil>
英文:

Yes, # indicates a fragment.

A way to solve it would be to escape the # character:

  1. connString := fmt.Sprintf(&quot;postgresql://postgres:password%s@192.168.1.10:5432/postgres&quot;, url.PathEscape(&quot;#&quot;))
  2. parsedUrl, _ := url.Parse(connString)
  3. fmt.Println(url.PathUnescape(parsedUrl.User.String()))

And the output:

  1. postgres:password# &lt;nil&gt;

答案2

得分: 1

你可以使用url.QueryEscape()函数。

示例

  1. package main
  2. import (
  3. "fmt"
  4. "net/url"
  5. )
  6. func main() {
  7. connString := `postgresql://postgres:` + url.QueryEscape(`password#`) + `@192.168.1.10:5432/postgres`
  8. xurl, err := url.Parse(connString)
  9. if err != nil {
  10. fmt.Println(err)
  11. }
  12. fmt.Println("=")
  13. fmt.Println(xurl.User.Username())
  14. fmt.Println(xurl.User.Password())
  15. fmt.Println("=")
  16. }
英文:

You can use url.QueryEscape()

Example

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;net/url&quot;
  5. )
  6. func main() {
  7. connString := `postgresql://postgres:` + url.QueryEscape(`password#`) + `@192.168.1.10:5432/postgres`
  8. xurl, err := url.Parse(connString)
  9. if err != nil {
  10. fmt.Println(err)
  11. }
  12. fmt.Println(&quot;=&quot;)
  13. fmt.Println(xurl.User.Username())
  14. fmt.Println(xurl.User.Password())
  15. fmt.Println(&quot;=&quot;)
  16. }

huangapple
  • 本文由 发表于 2021年8月28日 16:55:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/68962814.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定