【问题标题】:How start web server to open page in browser in golang?如何启动Web服务器以在golang的浏览器中打开页面?
【发布时间】:2017-01-12 05:18:20
【问题描述】:

如何使用 golang 在浏览器中临时打开网页?

就像这里是如何使用HTTPServer in python 完成的。

【问题讨论】:

    标签: http browser go server


    【解决方案1】:

    这是一个相当普遍的问题。您可以使用xdg-open 程序为您完成。只需从 Go 运行该过程。 xdg-open 将自行分叉,因此我们可以简单地使用 Run 并等待进程结束。

    package main
    
    import "os/exec"
    
    func main() {
        exec.Command("xdg-open", "http://example.com/").Run()
    }
    

    【讨论】:

    • 如果我想关闭xdg-open打开的标签页怎么办?
    • @RotimiBest 这是不可能的。
    【解决方案2】:

    您的问题有点误导,因为它询问如何在网络浏览器中打开本地页面,但您实际上想知道如何启动网络服务器以便可以在浏览器中打开它。

    对于后者(启动 Web 服务器以提供静态文件),您可以使用 http.FileServer() 函数。有关更详细的答案,请参阅:Include js file in Go templateWith golang webserver where does the root of the website map onto the filesystem>

    为您的/tmp/data 文件夹提供服务的示例:

    http.Handle("/", http.FileServer(http.Dir("/tmp/data")))
    panic(http.ListenAndServe(":8080", nil))
    

    如果您想提供动态内容(由 Go 代码生成),您可以使用 net/http 包并编写自己的处理程序来生成响应,例如:

    func myHandler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprint(w, "Hello from Go")
    }
    
    func main() {
        http.HandleFunc("/", myHandler)
        panic(http.ListenAndServe(":8080", nil))
    }
    

    对于第一个(在默认浏览器中打开页面),Go 标准库中没有内置支持。但这并不难,您只需执行特定于操作系统的外部命令。您可以使用这个跨平台解决方案(我也在我的github.com/icza/gox 库中发布,参见osx.OpenDefault()):

    // open opens the specified URL in the default browser of the user.
    func open(url string) error {
        var cmd string
        var args []string
    
        switch runtime.GOOS {
        case "windows":
            cmd = "cmd"
            args = []string{"/c", "start"}
        case "darwin":
            cmd = "open"
        default: // "linux", "freebsd", "openbsd", "netbsd"
            cmd = "xdg-open"
        }
        args = append(args, url)
        return exec.Command(cmd, args...).Start()
    }
    

    此示例代码取自Gowut(即Go Web UI Toolkit;披露:我是作者)。

    请注意,exec.Command() 会在需要时执行特定于操作系统的参数引用。因此,例如,如果 URL 包含 &,它将在 Linux 上正确转义,但是,它可能无法在 Windows 上运行。在 Windows 上,您可能必须自己手动引用它,例如将& 符号替换为"^&",并使用strings.ReplaceAll(url, "&", "^&") 之类的调用。

    使用它在您的默认浏览器中打开之前启动的网络服务器:

    open("http://localhost:8080/")
    

    最后一件事要注意:http.ListenAndServe() 阻塞并且永远不会返回(如果没有错误)。所以你必须在另一个 goroutine 中启动服务器或浏览器,例如:

    go open("http://localhost:8080/")
    panic(http.ListenAndServe(":8080", nil))
    

    查看此问题以了解如何在网络服务器启动后启动浏览器的其他替代方法:Go: How can I start the browser AFTER the server started listening?

    【讨论】:

    • 也许对 url 参数进行 ParseRequestURI 验证不会有任何危害。你永远不知道 SO 代码是如何在野外复制和粘贴的。
    • stackoverflow.com/a/32742904/3236818 解释了如何在服务器开始监听后启动浏览器。没有任何投票。
    【解决方案3】:

    上次我做了这样的事情,我在启动浏览器之前添加了一个短暂的延迟,以确保在浏览器发送第一个请求之前服务器有时间进行监听。在我的 Linux 系统上,xdg 的配置不是很正确,我没有修复 xdg 配置,而是使用“firefox”而不是“xdg-open”对其进行硬连线。在与 Web 服务器相同的机器上启动浏览器在开发中是一件好事。但是在部署中,Web 服务器很可能在无头远程系统上运行,并且简单地将初始 URL 打印到控制台以便从终端会话复制粘贴到远程服务器到本地浏览器中可能更有意义。

    package main
    
    import (
        "fmt"
        "net/http"
        "time"
    )
    
    func myHandler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprint(w, "Hello from Go")
    }
    
    func main() {
        http.HandleFunc("/", myHandler)
        go func() {
            <-time.After(100 * time.Millisecond)
            open("http://localhost:8080/")
        }()
        panic(http.ListenAndServe(":8080", nil))
    }
    

    【讨论】:

    • 嗨。您提供的代码有许多语法错误,包括未导入“net/http”、导入“os/exec”但未使用它以及调用未定义的“open”。您能否编辑您的代码(并对其进行测试)以帮助回答这个问题。谢谢。
    【解决方案4】:

    根据 Paul 的回答,这里有一个适用于 Windows 的解决方案:

    package main
    
    import (
        "log"
        "net/http"
        "os/exec"
        "time"
    )
    
    
    func main() {
        http.HandleFunc("/", myHandler)
        go func() {
            <-time.After(100 * time.Millisecond)
            err := exec.Command("explorer", "http://127.0.0.1:8080").Run()
            if err != nil {
                log.Println(err)
            }
        }()
    
        log.Println("running at port localhost:8080")
        log.Fatal(http.ListenAndServe(":8080", nil))
    }
    

    【讨论】:

      猜你喜欢
      • 2013-05-27
      • 2018-12-20
      • 2015-04-17
      • 2012-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-10
      • 1970-01-01
      相关资源
      最近更新 更多