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

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

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

问题

我有以下代码。

main.go:

package main

import "fmt"
import "net/url"

func main() {
    connString := "postgresql://postgres:password@192.168.1.10:5432/postgres"
    parsedUrl, err := url.Parse(connString)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println("=")
    fmt.Println(parsedUrl.User)
    fmt.Println("=")
}

执行结果:

$ go run main.go
=
postgres:password
=

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

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

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

=

=

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

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

英文:

I have next code.

main.go:

package main

import "fmt"
import "net/url"

func main() {
    connString := "postgresql://postgres:password@192.168.1.10:5432/postgres"
    parsedUrl, err := url.Parse(connString)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println("=")
    fmt.Println(parsedUrl.User)
    fmt.Println("=")
}

Execution:

$ go run main.go
=
postgres:password
=

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.

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

Then, run it again, it outputs as next:

=

=

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

是的,#表示一个片段。

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

connString := fmt.Sprintf("postgresql://postgres:password%s@192.168.1.10:5432/postgres", url.PathEscape("#"))

parsedUrl, _ := url.Parse(connString)

fmt.Println(url.PathUnescape(parsedUrl.User.String()))

输出结果为:

postgres:password# <nil>
英文:

Yes, # indicates a fragment.

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

connString := fmt.Sprintf(&quot;postgresql://postgres:password%s@192.168.1.10:5432/postgres&quot;, url.PathEscape(&quot;#&quot;))

parsedUrl, _ := url.Parse(connString)

fmt.Println(url.PathUnescape(parsedUrl.User.String()))

And the output:

postgres:password# &lt;nil&gt;

答案2

得分: 1

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

示例

package main

import (
	"fmt"
	"net/url"
)

func main() {
	connString := `postgresql://postgres:` + url.QueryEscape(`password#`) + `@192.168.1.10:5432/postgres`
	xurl, err := url.Parse(connString)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("=")

	fmt.Println(xurl.User.Username())
	fmt.Println(xurl.User.Password())
	fmt.Println("=")
}
英文:

You can use url.QueryEscape()

Example

package main

import (
	&quot;fmt&quot;
	&quot;net/url&quot;
)

func main() {
	connString := `postgresql://postgres:` + url.QueryEscape(`password#`) + `@192.168.1.10:5432/postgres`
	xurl, err := url.Parse(connString)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(&quot;=&quot;)

	fmt.Println(xurl.User.Username())
	fmt.Println(xurl.User.Password())
	fmt.Println(&quot;=&quot;)
}

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:

确定