web-dev-qa-db-ja.com

URLパスをpath.Join()と組み合わせます

Goでpath.Join()を使用してファイルパスでできるようにURLパスを結合する方法はありますか?

たとえば、 絶対パスと相対パスを組み合わせて新しい絶対パスを取得

path.Join("http://foo", "bar")を使用すると、http:/foo/bar

Golang Playground を参照してください。

35
Aleš

関数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

playground example

パス(スキーマまたはホストなど)を超えて結合する場合、または文字列がパス(クエリ文字列を含むなど)を超える場合は、 ResolveReference を使用します。

55
Cerise Limón

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))
}
22
mmmkay

これに対する簡単なアプローチは、不要な/を削除して参加することです。以下はfuncの例です

func JoinURL(base string, paths ...string) string {
    p := path.Join(paths...)
    return fmt.Sprintf("%s/%s", strings.TrimRight(base, "/"), strings.TrimLeft(p, "/"))
}

使用法は

b := "http://my.domain.com/api/"
u := JoinURL(b, "/foo", "bar/", "baz")
fmt.Println(u)

これにより、エラーを確認/返す必要がなくなります。

0
vbranden

私の目的に合ったこのユーティリティ関数を書きました:

func Join(basePath string, paths ...string) (*url.URL, error) {

    u, err := url.Parse(basePath)

    if err != nil {
        return nil, fmt.Errorf("invalid url")
    }

    p2 := append([]string{u.Path}, paths...)

    result := path.Join(p2...)

    u.Path = result

    return u, nil
}

https://play.golang.org/p/-QNVvyzacMM

0
Brent