将URL路径与path.Join()组合在一起

Ale*_*leš 43 url path go

Go中是否有一种方法可以像使用文件路径一样组合URL路径path.Join()

例如,参见例如组合绝对路径和相对路径以获得新的绝对路径.

当我使用时path.Join("http://foo", "bar"),我明白了http:/foo/bar.

Golang Playground看到.

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)

playground example

如果您组合的不仅仅是路径(例如方案或主机),或者字符串不仅仅是路径(例如,它包含查询字符串),那么请使用ResolveReference.

  • @ CodyA.Ray path软件包在所有平台上都使用正斜杠分隔的路径。在所有平台(包括Windows)上,“ path.Join(u.Path,“ bar.html”)”生成的路径均为“ /foo/bar.html”。路径套件[字面使用正斜线](https://github.com/golang/go/blob/9a0a150c9f50f920f35cc4d50ac3005503f44f2d/src/path/path.go#L158)。 (3认同)
  • @ CodyA.Ray该代码在Windows上可以正常工作。[path package](https://godoc.org/path)与正斜杠分隔的路径一起使用,如软件包文档第一段所述。[path / filepath](https://godoc.org/path/filepath)软件包在Windows上使用反斜杠,但这不是此答案中使用的软件包。 (2认同)

mmm*_*kay 23

net/url包中的ResolveReference()

接受的答案不适用于包含.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)


Mik*_*age 9

在 1.19 中,标准库中将有一个新函数可以非常巧妙地解决这个问题。

u, err := url.JoinPath("http://host/foo", "bar/")
Run Code Online (Sandbox Code Playgroud)

https://go.dev/play/p/g422ockBq0q?v=gotip


vbr*_*den 8

一个简单的方法是修剪您不想要的 / 并加入。这是一个示例函数

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)

这消除了检查/返回错误的需要


rus*_*tyx 8

要将一个URL与另一个URL或一条路径连接起来,有URL.Parse()

func (u *URL) Parse(ref string) (*URL, error)
Run Code Online (Sandbox Code Playgroud)

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)