Go中是否有一种方法可以像使用文件路径一样组合URL路径path.Join()
?
例如,参见例如组合绝对路径和相对路径以获得新的绝对路径.
当我使用时path.Join("http://foo", "bar")
,我明白了http:/foo/bar
.
Cer*_*món 65
函数path.Join期望一个路径,而不是URL.解析URL以获取路径并加入该路径:
u, err := url.Parse("http://foo")
u.Path = path.Join(u.Path, "bar.html")
s := u.String() // prints http://foo/bar.html
Run Code Online (Sandbox Code Playgroud)
如果您组合的不仅仅是路径(例如方案或主机),或者字符串不仅仅是路径(例如,它包含查询字符串),那么请使用ResolveReference.
mmm*_*kay 23
接受的答案不适用于包含.html或.img等文件结尾的相对URL路径.ResolveReference()函数是在go中连接url路径的正确方法.
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
u, err := url.Parse("../../..//search?q=dotnet")
if err != nil {
log.Fatal(err)
}
base, err := url.Parse("http://example.com/directory/")
if err != nil {
log.Fatal(err)
}
fmt.Println(base.ResolveReference(u))
}
Run Code Online (Sandbox Code Playgroud)
在 1.19 中,标准库中将有一个新函数可以非常巧妙地解决这个问题。
u, err := url.JoinPath("http://host/foo", "bar/")
Run Code Online (Sandbox Code Playgroud)
https://go.dev/play/p/g422ockBq0q?v=gotip
一个简单的方法是修剪您不想要的 / 并加入。这是一个示例函数
func JoinURL(base string, paths ...string) string {
p := path.Join(paths...)
return fmt.Sprintf("%s/%s", strings.TrimRight(base, "/"), strings.TrimLeft(p, "/"))
}
Run Code Online (Sandbox Code Playgroud)
用法是
b := "http://my.domain.com/api/"
u := JoinURL(b, "/foo", "bar/", "baz")
fmt.Println(u)
Run Code Online (Sandbox Code Playgroud)
这消除了检查/返回错误的需要
要将一个URL
与另一个URL
或一条路径连接起来,有URL.Parse()
:
Run Code Online (Sandbox Code Playgroud)func (u *URL) Parse(ref string) (*URL, error)
Parse 在接收者的上下文中解析 URL。提供的 URL 可以是相对的或绝对的。
nil
解析失败时,Parse 返回err
,否则其返回值与 相同ResolveReference
。
func TestURLParse(t *testing.T) {
baseURL, _ := url.Parse("http://foo/a/b/c")
url1, _ := baseURL.Parse("d/e")
require.Equal(t, "http://foo/a/b/d/e", url1.String())
url2, _ := baseURL.Parse("../d/e")
require.Equal(t, "http://foo/a/d/e", url2.String())
url3, _ := baseURL.Parse("/d/e")
require.Equal(t, "http://foo/d/e", url3.String())
}
Run Code Online (Sandbox Code Playgroud)