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

时间:2016-01-08 01:16:20

标签: url go path

Go中是否有一种方法可以使用path.Join()与文件路径类似地组合URL路径?

例如,参见例如Combine absolute path and relative path to get a new absolute path

当我使用path.Join("http://foo", "bar")时,我得到http:/foo/bar

Golang Playground

5 个答案:

答案 0 :(得分:47)

函数path.Join期望路径,而不是URL。解析URL以获取路径并加入该路径:

<?php 
$count = 0;

while (have_posts()) : the_post(); $count++; 

    if ( $count == 1 ) echo '<div class="top">';
    if ( $count > 5 ) echo '</div><div class="bottom">';

    the_title();
    if ( $count > 5 ) the_excerpt();

endwhile;

echo "</div>"
?>

playground example

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

答案 1 :(得分:21)

ResolveReference() in net/url package

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

答案 2 :(得分:0)

我编写了这个实用程序功能,该功能可以满足我的目的:

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

答案 3 :(得分:0)

一种简单的方法是修剪不需要的/并加入。这是一个示例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)

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

答案 4 :(得分:0)

要将URL与另一个URL或路径连接在一起,请使用URL.Parse()

func (u *URL) Parse(ref string) (*URL, error)

Parse在接收者的上下文中解析URL。提供的URL 可能是相对绝对。解析失败时,解析返回nilerr, 否则其返回值与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())
}