Go语言拼接URL路径有多种方法建议用ResolveReference。

JoinPath

JoinPath会把多个多个路径合并成一个路径,并且处理.././,多个//合并成单个/

package main

import (
	"fmt"
	"net/url"
)

func main() {
	u1 := "http://example.com/directory/"
	u2 := "../../..//search?q=dotnet"
	u3 := "/dir1/dir2/search?q=dotnet"

	j1, _ := url.JoinPath(u1, u2)
	j2, _ := url.JoinPath(u1, u3)
	fmt.Println(j1)
	// http://example.com/search%3Fq=dotnet
	fmt.Println(j2)
	// http://example.com/directory/dir1/dir2/search%3Fq=dotnet
}

ResolveReference

ResolveReference会处理绝对路径和相对路径。

package main

import (
	"fmt"
	"log"
	"net/url"
)

func main() {
	u1, _ := url.Parse("../../..//search?q=dotnet")
	u2, _ := url.Parse("/dir1/dir2/search?q=dotnet")
	base, err := url.Parse("http://example.com/directory/")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(base.ResolveReference(u1))
	// http://example.com/search?q=dotnet
	fmt.Println(base.ResolveReference(u2))
	// http://example.com/dir1/dir2/search?q=dotnet
}

path.Join

path主要是对斜杠放个的路径。

package main

import (
	"fmt"
	"log"
	"net/url"
	"path"
)

func main() {
	u, err := url.Parse("http://example.com/test/")
	if err != nil {
		log.Fatal(err)
	}
	u.Path = path.Join(u.Path, "../bar.html")
	s := u.String()
	fmt.Println(s) // http://example.com/bar.html

}

参考

https://pkg.go.dev/net/url@go1.19beta1#JoinPathhttp://doc.golang.ltd/pkg/net_url.htm