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

huangapple go评论88阅读模式
英文:

How start web server to open page in browser in golang?

问题

你好!以下是你要翻译的内容:

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

就像这里使用Python的HTTPServer那样。

英文:

How do I temporarily open a web page in browser using golang?

Like here is how it is done using HTTPServer in python.

答案1

得分: 35

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

对于后者(启动一个用于提供静态文件的Web服务器),你可以使用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函数在用户的默认浏览器中打开指定的URL。
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, "&", "\"^&\"")进行替换。

使用这个方法在默认浏览器中打开先前启动的Web服务器:

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

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

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

查看这个问题,了解在Web服务器启动后如何启动浏览器的其他替代方法:https://stackoverflow.com/questions/32738188/go-how-can-i-start-the-browser-after-the-server-started-listening/32738973#32738973

英文:

Your question is a little misleading as it asks how to open a local page in the web browser, but you actually want to know how to fire up a web server so it can be opened in the browser.

For the latter (firing up a web server to serve static files), you may use the http.FileServer() function. For answers presenting it in greater detail, see: Include js file in Go template and With golang webserver where does the root of the website map onto the filesystem>.

Example serving your /tmp/data folder:

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

If you want to serve dynamic content (generated by Go code), you can use the net/http package and write your own handler generating the response, e.g.:

func myHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello from Go")
}

func main() {
    http.HandleFunc("/", myHandler)
    panic(http.ListenAndServe(":8080", nil))
}

As to the first (to open a page in your default browser), there is no builtin support in the Go standard library. But it's not that hard, you just have to execute an OS-specific external command. You may use this cross-platform solution (which I also released in my github.com/icza/gox library, see 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()
}

This example code is taken from Gowut (which is Go Web UI Toolkit; disclosure: I'm the author).

Note that exec.Command() performs OS-specific argument quoting if needed. So for example if the URL contains &, it will be properly escaped on Linux, however, it might not work on Windows. On Windows you might have to manually quote it yourself, e.g. with replacing & signs with "^&" with a call like strings.ReplaceAll(url, "&", "^&").

Using this to open the previously started webserver in your default browser:

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

One last thing to note: http.ListenAndServe() blocks and never returns (if there is no error). So you have to start the server or the browser in another goroutine, for example:

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

Check out this question for other alternatives how to start the browser after the webserver has been started: https://stackoverflow.com/questions/32738188/go-how-can-i-start-the-browser-after-the-server-started-listening/32738973#32738973

答案2

得分: 0

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

package main

import "os/exec"

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

It is quite a general problem. You can use xdg-open program to do it for you. Just run the process from Go. The xdg-open will fork by itself so we can just simply use Run and wait for the end of process.

package main

import "os/exec"

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

答案3

得分: 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))
}

请注意,这是一个使用Go语言编写的程序,它创建了一个简单的HTTP服务器,并在浏览器中打开了一个URL。

英文:

Building off of Paul's answer, here is a solution that works on Windows:

package main

import (
	&quot;log&quot;
	&quot;net/http&quot;
	&quot;os/exec&quot;
	&quot;time&quot;
)


func main() {
	http.HandleFunc(&quot;/&quot;, myHandler)
	go func() {
		&lt;-time.After(100 * time.Millisecond)
		err := exec.Command(&quot;explorer&quot;, &quot;http://127.0.0.1:8080&quot;).Run()
		if err != nil {
			log.Println(err)
		}
	}()

	log.Println(&quot;running at port localhost:8080&quot;)
	log.Fatal(http.ListenAndServe(&quot;:8080&quot;, nil))
}

答案4

得分: 0

对于Windows系统,只需运行以下命令:

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

请注意,这是一段Go语言代码,用于在Windows系统中打开指定的URL链接。

英文:

for windows simply run:

exec.Command(&quot;rundll32&quot;, &quot;url.dll,FileProtocolHandler&quot;, url).Run()

答案5

得分: -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))
}
英文:

Last time I did something like this, I added a short delay before starting up the browser, to make sure the server had time to be listening before the browser sent the first request. On my Linux system, xdg wasn't configured quite right and rather than fixing the xdg configuration, I just hardwired it with "firefox" rather than "xdg-open". Starting the browser on the same machine as the web server made for a good thing in development. But in deployment, the web server is likely to be running on a headless remote system and it might make more sense to simply print the initial URL to the console for a copy-paste from a terminal session to the remote server into a local browser.

package main

import (
	&quot;fmt&quot;
	&quot;net/http&quot;
	&quot;time&quot;
)

func myHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, &quot;Hello from Go&quot;)
}

func main() {
	http.HandleFunc(&quot;/&quot;, myHandler)
	go func() {
		&lt;-time.After(100 * time.Millisecond)
		open(&quot;http://localhost:8080/&quot;)
	}()
	panic(http.ListenAndServe(&quot;:8080&quot;, nil))
}

huangapple
  • 本文由 发表于 2016年9月5日 02:49:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/39320371.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定