Goでpath.Join()
を使用してファイルパスでできるようにURLパスを結合する方法はありますか?
たとえば、 絶対パスと相対パスを組み合わせて新しい絶対パスを取得 。
path.Join("http://foo", "bar")
を使用すると、http:/foo/bar
。
Golang Playground を参照してください。
関数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
パス(スキーマまたはホストなど)を超えて結合する場合、または文字列がパス(クエリ文字列を含むなど)を超える場合は、 ResolveReference を使用します。
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))
}
これに対する簡単なアプローチは、不要な/を削除して参加することです。以下は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)
これにより、エラーを確認/返す必要がなくなります。
私の目的に合ったこのユーティリティ関数を書きました:
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
}