用 Go 创建一个 Web 应用

开发 前端
如果你看到上面的结果,你已经成功地创建了你的第一个 Golang 网络和文件服务器。恭喜!如果您想进一步探索 Golang Web 服务器,Golang HTTP 包文档中有很多很好的例子。

客户端/服务器

假设你开发了一个使用 Go 语言编写的程序来管理你的照片库,这个程序可以在你的电脑上处理你的照片。你可能想与其他家庭成员分享这些照片,为此,你可以通过电子邮件发送包含所有照片的附件。但如果你拍了一万张照片,这种解决方案可能是不可行的。

您可以将内容自动上传到您最喜爱的社交网络。如果您必须一次处理一张照片,该操作可能会变得非常耗时。另一种解决方案可能是将您的程序直接插入社交网络系统,以编程方式上传图片。

我们可以借助社交网络公开的 API 来做到这一点。您可以通过直接调用它们的 API 将图片推送到 for 循环中。

在这种情况下,您将使用一个 API。你是客户端。社交网络代表服务器。

调用 API 意味着按照精确的文档向 Web 服务器发出 HTTP(s) 请求。客户端和服务器这两个术语很重要,您必须记住它们。作为客户端,我们使用(或消费)API。服务器是一个计算机程序,旨在接受和响应客户端的 API 调用。

图片

Go 语言在创建简单高效的 Web 服务器方面很有优势。Go 语言提供了内置的 HTTP 包,其中包含了快速创建 Web 或文件服务器所需的实用工具。这使得使用 Go 语言创建 Web 服务器和 Web 服务变得简单和高效。

创建 server.go 文件

在上一篇文章中,我们学习了 net/http 包中的 Request 和 Response ,所以这里我们可以直接使用:

package main

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

func main() {

  http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
   fmt.Fprintf(w, "Hello!")
  })

 fmt.Printf("Starting server at port 8088\n")

 if err := http.ListenAndServe(":8088", nil); err != nil {
  log.Fatal(err)
 }
}

运行 go run server.go ,可以在终端上看到如下输出:

Starting server at port 8088

在此阶段,我们将创建一个实际在端口 8088 上提供服务并可以响应传入 GET 请求的 Web 服务器。让我们在端口 8088 启动 Web 服务器。ListenAndServe() 方法由我们在第一步中导入的 http 数据包导出。此方法允许我们启动 Web 服务器并指定端口以侦听传入请求。请注意,端口参数需要作为以冒号标点符号开头的字符串传递。第二个参数接受一个处理程序来为 HTTP/2 配置服务器,将 nil 作为第二个参数传递。

我们将使用 HandleFunc() 函数将路由处理程序添加到 Web 服务器。第一个参数接受它需要监听的路径 /hello。在这里,您告诉服务器监听对 http://localhost:8088/hello 的任何传入请求。第二个参数接受一个函数,该函数包含正确响应请求的业务逻辑。

默认情况下,此函数接受 ResponseWriter 以发回响应,并接受 Request 对象以提供有关请求本身的更多信息。例如,您可以访问有关已发送标头的信息,这对于验证请求很有用。

图片

如您所见,处理程序发送了一个“Hello!”消息,因为我们将此响应传递给 ResponseWriter。

路由添加基本校验

不用说,安全很重要。让我们探索一些增强 Go Web 服务器安全性的基本策略。在我们这样做之前,我们应该花点时间来提高代码的可读性。让我们创建 helloHandler 函数,它包含与 /hello 请求相关的所有逻辑。

func helloHandler(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path != "/hello" {
        http.Error(w, "404 not found.", http.StatusNotFound)
        return
    }

    if r.Method != "GET" {
        http.Error(w, "Method is not supported.", http.StatusNotFound)
        return
    }


    fmt.Fprintf(w, "Hello!")
}

此处理程序使用 Request 对象检查请求的路径是否正确。这是一个非常基本的示例,说明如何使用 Request 对象。

如果路径不正确,服务器将向用户返回 StatusNotFound 错误。要向用户写入错误,您可以使用 http.Error 方法。请注意,StatusNotFound 代码对应于 404 错误。所有状态代码都可以在 Golang 文档中找到。

接下来,我们添加一个检查来验证请求的类型。如果该方法不对应于 GET,则服务器返回一个新错误。当两个检查都通过时,服务器返回其成功响应“Hello!”。

我们需要做的最后一件事是修改 main() 函数中的 handleFunc 函数以接受上面的 helloHandler 函数。

http.HandleFunc("/hello", helloHandler)

完整的 server.go 文件如下:

package main

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

func helloHandler(w http.ResponseWriter, r *http.Request) {
 if r.URL.Path != "/hello" {
  http.Error(w, "404 not found", http.StatusNotFound)
  return
 }

 if r.Method != "GET" {
  http.Error(w, "Method is not supported", http.StatusNotFound)
  return
 }

 fmt.Fprintf(w, "Hello!")
}

func main() {

 http.HandleFunc("/hello", helloHandler)

 fmt.Printf("Starting server at port 8088\n")

 if err := http.ListenAndServe(":8088", nil); err != nil {
  log.Fatal(err)
 }
}

接下来,我们将使用 go run server.go 启动 Go Web 服务器。您可以使用 Postman 或 cURL 等工具向 http://localhost:8088/hello 发送 POST 请求来测试您的安全性。我们将得到与上一次相同的结果。

启动静态 Web 服务器

在这一步中,我们将创建一个简单的文件服务器来托管静态文件。这将是对 Web 服务器的一个非常简单的添加。为确保我们有内容可在 Web 服务器上提供服务,让我们新建一个位于 static 文件夹中的 index.html 文件。为了简单起见,只需在文件中添加一个标题为“Go Server”的标题。如果您愿意,可以添加更多文件或样式文件以使您的 Web 服务器看起来更漂亮一些。

新建一个 index.html 文件:

<html>
  <head>
    <title>Learn Go</title>
  </head>
  <body>
    <h2>Go Server</h2>
  </body>
</html>

要为 static 文件夹提供服务,您必须向 server.go 添加两行代码。第一行代码使用 FileServer 函数创建文件服务器对象。此函数接受 http.Dir 类型的路径。因此,我们必须将字符串路径“./static”转换为 http.Dir 路径类型。

不要忘记指定 Handle 路由,它接受路径和文件服务器。此函数的作用与 HandleFunc 函数相同,但有一些细微差别。有关 FileServer 对象的更多信息,请查看文档。

func main() {
    fileServer := http.FileServer(http.Dir("./static")) 
    http.Handle("/", fileServer)
    http.HandleFunc("/hello", helloHandler)


    fmt.Printf("Starting server at port 8088\n")
    if err := http.ListenAndServe(":8088", nil); err != nil {
        log.Fatal(err)
    }
}

是时候尝试代码了。使用 go run server.go 启动服务器并访问 http://localhost:8088/。你应该看到:

图片

接受表单提交 POST 请求

最后,Web 服务器必须响应表单提交。让我们向 static 文件夹中的 form.html 文件添加一些内容。请注意,表单操作已发送到 /form。这意味着来自表单的 POST 请求将被发送到 http://localhost:8088/form。表单本身要求输入两个变量:name 和 address。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    <div>
      <form method="POST" actinotallow="/form">
        <label>Name</label><input name="name" type="text" value="" />
        <label>Address</label><input name="address" type="text" value="" />
        <input type="submit" value="submit" />
      </form>
    </div>
  </body>
</html>

下一步是创建处理程序来接受 /form 请求。 form.html 文件已经通过 FileServer 提供,可以通过 http://localhost:8088/form.html 访问。

首先,该函数必须调用 ParseForm() 来解析原始查询并更新 r.PostForm 和 r.Form。这将允许我们通过 r.FormValue 方法访问 name 和 address 值。

在函数的末尾,我们使用 fmt.Fprintf 将这两个值写入 ResponseWriter。

func formHandler(w http.ResponseWriter, r *http.Request) {
    if err := r.ParseForm(); err != nil {
        fmt.Fprintf(w, "ParseForm() err: %v", err)
        return
    }
    fmt.Fprintf(w, "POST request successful")
    name := r.FormValue("name")
    address := r.FormValue("address")

    fmt.Fprintf(w, "Name = %s\n", name)
    fmt.Fprintf(w, "Address = %s\n", address)
}

不要忘记将新的表单处理程序路由添加到 main() 函数。

http.HandleFunc("/form", formHandler)

最后的 server.go 文件如下:

package main

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

func helloHandler(w http.ResponseWriter, r *http.Request) {
 if r.URL.Path != "/hello" {
  http.Error(w, "404 not found", http.StatusNotFound)
  return
 }

 if r.Method != "GET" {
  http.Error(w, "Method is not supported", http.StatusNotFound)
  return
 }

 fmt.Fprintf(w, "Hello!")
}

func formHandler(w http.ResponseWriter, r *http.Request) {
 if err := r.ParseForm(); err != nil {
  fmt.Fprintf(w, "ParseForm() err: %v", err)
  return
 }
 fmt.Fprintf(w, "POST request successful\n")
 name := r.FormValue("name")
 address := r.FormValue("address")

 fmt.Fprintf(w, "Name = %s\n", name)
 fmt.Fprintf(w, "Address = %s\n", address)
}

func main() {

 // http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
 //  fmt.Fprintf(w, "Hello!")
 // })

 fileServer := http.FileServer(http.Dir("./static"))
 http.Handle("/", fileServer)
 http.HandleFunc("/hello", helloHandler)

 http.HandleFunc("/form", formHandler)

 fmt.Printf("Starting server at port 8088\n")

 if err := http.ListenAndServe(":8088", nil); err != nil {
  log.Fatal(err)
 }
}

表单处理程序测试

我们可以通过使用 go run server.go 启动服务器来测试表单。当服务器启动时,访问 http://localhost:8088/form.html。您应该看到两个输入字段和一个提交按钮。

图片

填写完表格后,点击提交按钮。服务器应处理您的 POST 请求并在 http://localhost:8088/form 响应页面上向您显示结果,例如以下响应:

图片

如果你看到上面的结果,你已经成功地创建了你的第一个 Golang 网络和文件服务器。恭喜!如果您想进一步探索 Golang Web 服务器,Golang HTTP 包文档中有很多很好的例子。

官方文档:Writing Web Applications

责任编辑:武晓燕 来源: 宇宙之一粟
相关推荐

2014-10-15 11:01:02

Web应用测试应用

2011-05-11 10:58:39

iOS

2014-04-14 15:54:00

print()Web服务器

2019-07-05 08:39:39

GoSQL解析器

2022-06-07 07:21:19

Python内置库命令行

2009-01-19 11:07:42

C#Web.NET

2017-06-08 15:53:38

PythonWeb框架

2021-11-10 09:10:46

JS 录屏功能JavaScript

2021-04-25 08:58:00

Go拍照云盘

2021-04-15 08:55:51

Go struc代码

2019-05-08 14:37:49

Web服务器HTTP

2022-09-19 08:07:28

Goweb 程序

2020-12-08 08:46:07

GoJava工具

2010-08-13 13:05:30

Flex应用程序

2022-04-01 15:18:42

Web 框架网络通信

2015-10-12 16:45:26

NodeWeb应用框架

2023-09-21 08:00:00

ChatGPT编程工具

2020-07-03 10:21:48

Go框架Docker

2024-01-08 08:36:29

HTTPGo代理服务器

2024-01-02 00:18:56

Buffalo项目Go Web框架
点赞
收藏

51CTO技术栈公众号