如何在golang中启动Web服务器在浏览器中打开页面?

问题描述 投票:0回答:6

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

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

http browser go server
6个回答
36
投票

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

对于后者(启动网络服务器来提供静态文件),您可以使用

http.FileServer()
函数。有关更详细介绍的答案,请参阅:在 Go 模板中包含 js 文件使用 golang Web 服务器,网站的根目录映射到文件系统的位置>

提供

/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:如何在服务器开始侦听后启动浏览器?


0
投票

这是一个相当普遍的问题。您可以使用

xdg-open
程序来为您完成。只需从 Go 运行该流程即可。
xdg-open
会自行分叉,因此我们可以简单地使用
Run
并等待进程结束。

package main

import "os/exec"

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

0
投票

基于 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))
}

0
投票

对于 Windows,只需运行:

exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Run()

0
投票

以上所有解决方案在Linux下均无效。谁能分享一下 Linux 的解决方案吗?


-2
投票
上次我做这样的事情时,我在启动浏览器之前添加了短暂的延迟,以确保服务器在浏览器发送第一个请求之前有时间进行侦听。在我的 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)) }
    
© www.soinside.com 2019 - 2024. All rights reserved.