Golang笔记:使用http包实现基础WebServer功能

2023-11-18

目的

WebServer是一种非常常用的功能,Golang的高并发特性在处理此类工作中也有较大的优势,同时借助标准库中的 net/http 包可以非常快速的编写WebServer应用。这篇文章将简单记录下相关内容。

https://pkg.go.dev/net/http

Package http provides HTTP client and server implementations.

监听请求并响应

WebServer本质上来说很简单,主要可以为两步:

  • 监听某个端口号上收到的HTTP数据;
  • 根据收到的HTTP请求中的路径执行对应的操作;

下面是个简单的示例:

package main

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

func hello(w http.ResponseWriter, r *http.Request) { //回调函数,回调函数将在协程中运行
	time.Sleep(4 * time.Second)
	fmt.Fprintf(w, "Hello, you've requested: %s\n", r.URL.Path) // 向客户端应答数据
}

func naisu(w http.ResponseWriter, r *http.Request) { //回调函数
	fmt.Fprintln(w, "Naisu 233!") // 向客户端应答数据
}

func main() {
	http.HandleFunc("/", hello)      // 设置路由地址与对应回调函数
	http.HandleFunc("/naisu", naisu) // 实际应用中通常根据需求设置多个路由地址与对应回调函数

	err := http.ListenAndServe(":80", nil) // 启动WebServer,监听80端口,可以在本机浏览器中通过 http://localhost:<端口号><路由地址> 进行访问(80端口可以省略:80)
	// err := http.ListenAndServe("0.0.0.0:80", nil) // 在本机所有网卡上进行监听,同网段下的设备可以通过 http://本机IP地址/ 进行访问
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

在这里插入图片描述

上面示例中核心涉及的就两个方法:

  • func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
    该方法用于设置路由和对应的回调函数;
  • func ListenAndServe(addr string, handler Handler) error
    该方法用于监听某个端口号,启动WebServer;
    该方法还有个变种 ListenAndServeTLS 用于启动HTTPS服务;

请求解析

上面的回调函数原型是 func(http.ResponseWriter, *http.Request) 包含了请求对象和返回的响应对象,实际操作中也主要就是根据请求的内容和业务逻辑进行响应。

下面例子中打印了请求对象中的一些内容:

package main

import (
	"fmt"
	"net/http"
)

func hello(w http.ResponseWriter, r *http.Request) {
	fmt.Println(r.Method)
	fmt.Println(r.URL)
	fmt.Println(r.Header) // 请求头,各个请求头字段以字典形式保存
	fmt.Println(r.Body)
	fmt.Println(r.ContentLength)
}

func main() {
	http.HandleFunc("/", hello)

	http.ListenAndServe(":80", nil)
}

在这里插入图片描述
上面演示中 /favicon.ico 是浏览器自己发起的请求。

更多使用方法可以查看官方文档中 Request 类型和相关的方法。

进行响应

进行响应主要就是设置响应头字段,设置状态码,写正文内容这些。

package main

import (
	"io"
	"net/http"
)

func hello(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Trailer", "AtEnd1, AtEnd2")                 // 设置(添加)响应头字段
	w.Header().Add("Trailer", "AtEnd3")                         // 添加响应头字段
	w.Header().Set("Content-Type", "text/plain; charset=utf-8") // 添加响应头字段
	w.WriteHeader(http.StatusOK)                                // 写状态码
	io.WriteString(w, "Hello Naisu.\n")                         // 响应body内容
	// 注意写头字段、状态码和body的顺序
}

func main() {
	http.HandleFunc("/", hello)

	http.ListenAndServe(":80", nil)
}

在这里插入图片描述

更多使用方法可以查看官方文档中 ResponseWriter 类型和相关的方法。

静态文件服务

对于WebServer来说静态文件服务是非常常用的功能。静态文件服务最常用的就是提供前端网页文件等,所以我们这里弦准备一个名为 index.html 文件,放在当前项目目录下,文件内容如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
</head>
<body>
    <h1 style="color: #4DD498;">Hello Naisu!</h1>
</body>
</html>

然后使用下面方式启动静态文件服务:

package main

import (
	"net/http"
)

func main() {
	fs := http.FileServer(http.Dir("./"))       // 设置静态文件存放路径,可以使用绝对或相对路径
	http.Handle("/", http.StripPrefix("/", fs)) // 设置静态文件路由处理,通过 http://localhost/文件名 进行访问
	// http.Handle("/static/", http.StripPrefix("/static/", fs)) // 通过 http://localhost/static/文件名 进行访问
	// 设置静态文件存放路径根目录下的 index.html 文件可以不加文件名进行访问

	http.ListenAndServe(":80", nil)
}

在这里插入图片描述

当然只有一个文件的话也可以使用 func ServeFile(w ResponseWriter, r *Request, name string) 方法来处理,比如上面情况下也可以指定路径返回指定文件:

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    http.ServeFile(w, r, "index.html")
})

静态文件服务除了上面这样简单使用外,也可以进行定制,比如官方文档中的例子,过滤了设置的目录下所有文件名以 . 开头的文件:
https://pkg.go.dev/net/http#example-FileServer-DotFileHiding

总结

Golang使用标准库中的 net/http 来编写WebServer是比较简单的。更多教程可以参考下面链接:
https://gowebexamples.com/
https://github.com/astaxie/build-web-application-with-golang

实际工作中如果需求比较全面的话全部细节功能都从头实现的话就比较麻烦了。Golang有一个非常出名的用于Web开发的工具库Gorilla,实现了很多常用的功能:
https://www.gorillatoolkit.org/

对于更加复杂的项目也可以直接使用现成的框架。Gin是一个Golang的主流的轻量级Web框架,其官网和项目地址如下:
https://gin-gonic.com/
https://github.com/gin-gonic/gin

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Golang笔记:使用http包实现基础WebServer功能 的相关文章

  • 在 Tomcat 上部署 Java Web 项目,无需 WAR 或 EAR

    我有一个 Java Web 项目 Struts Spring 在我的本地主机上完美运行 我必须将其部署在我的网站上 但虚拟主机提供的 Tomcat Manager 界面显示 由于安全原因 它无法上传 WAR 文件 当联系技术支持时 我被告知
  • 如何使用 http 将 Android 中的文件从移动设备发送到服务器?

    在android中 如何使用http将文件 数据 从移动设备发送到服务器 很简单 您可以使用 Post 请求并将文件作为二进制 字节数组 提交 String url http yourserver File file new File En
  • 将 HttpApi 与 I/O 完成端口结合使用

    我刚刚偶然发现了微软的HTTP 服务器 API http msdn microsoft com en us library aa364510 28v vs 85 29 aspx 简介中写道 HTTP 服务器 API 使应用程序能够通过 HT
  • 如何确定服务器是否支持 Range 标头?

    我一直在尝试使用 Range 标头值从特定点流式传输音频 但我总是从一开始就得到歌曲 我正在通过程序执行此操作 因此不确定问题是否出在我的代码中或服务器上 如何确定服务器是否支持 Range 标头参数 Thanks 方式HTTP规范 htt
  • 我应该使用多个 HttpClient 来进行批量异步 GET 请求吗?

    我有一个场景 我需要在尽可能短的时间内发出大量 GET 请求 想想大约 1000 个 我知道通常最好保留一个客户端并尽可能重用它 Create Single HTTP Client HttpClient client new HttpCli
  • 使用特定 HTTP 方法链接到页面 (DELETE)

    如何像 Rails 那样链接到页面并让浏览器使用 DELETE 方法调用它 我试过 a href DELETE ME a 但不起作用 我使用 Node js 所以我可以用它来处理 DELETE 方法 你不能 链接只会触发 GET 请求 您可
  • Netty Nio java 中的通信

    我想在 Netty nio 中创建一个具有两个客户端和一个服务器的通信系统 更具体地说 首先 我希望当两个客户端与服务器连接时从服务器发送消息 然后能够在两个客户端之间交换数据 我正在使用本示例提供的代码 https github com
  • Firebase Auth - 最近登录多长时间

    我有一个个人资料选项卡 用户可以在其中按编辑并编辑他们的个人资料 我只想在必要时才需要他们的密码 所以想知道用户登录的时间是多少毫秒 这使得它不是最近登录 其中firebase会抛出错误 auth requires recent login
  • HttpWebRequest vs Webclient(特殊场景)

    我知道这个问题之前已经回答过thread https stackoverflow com questions 1694388 webclient vs httpwebrequest httpwebresponse 但我似乎找不到详细信息 在
  • Android - API 请求

    我开发了一个应用程序 它也在 iPhone 上 问题出在 api 请求上 我为所有请求设置了超时 有时会出现 30 60 秒的中断 看起来这个应用程序执行了几个请求 然后就中断了 一直超时 大约 45 秒后一切正常 不知道是服务器问题还是安
  • 使用 php ping 网站

    我想创建一个 php 脚本 它将 ping 一个域并列出响应时间以及请求的总大小 这将用于监控网站网络 我尝试过curl 这是我到目前为止的代码 function curlTest2 url clearstatcache return if
  • 面向服务的架构 - AMQP 或 HTTP

    一点背景 非常大的整体 Django 应用程序 所有组件都使用相同的数据库 我们需要分离服务 以便我们可以独立升级系统的某些部分而不影响其余部分 我们使用 RabbitMQ 作为 Celery 的代理 现在我们有两个选择 使用 REST 接
  • 诸如用于测试 HTTP 请求的虚拟 REST 服务器之类的东西? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我一直在四处寻找 但找不到任何这样的网站 我想知道是否有一些虚拟服务器可以响应测试 GET 请求并返回
  • 如何在flutter项目中使用http拦截器?

    我必须向我的所有 Api 添加标头 有人告诉我为此使用 http 拦截器 但我无法理解如何做到这一点 因为我是颤振的新手 谁能帮我举个例子吗 您可以使用http 拦截器 https pub dev packages http interce
  • Chrome:网络元素自动移动

    我正在开发一个网络项目 在过去的两周里 我正在进行学期考试 所以我要休息一下 现在 既然他们已经结束了 我又继续我的工作了 但我发现我的一些Web 元素 如按钮 span 在 Chrome 上移动了一些像素 在 IE 和 Mozilla 上
  • 如何防止桌面浏览器(Chrome、Safari)缩放网页

    我尝试使用以下元视图端口标记来防止浏览器缩放 但这不起作用 我知道这是可能的 因为我的缩放在此网站上被阻止 未来主义 xyz http futurism xyz 该网站的视口标签是这样的
  • 用 C++ 解析 HTTP 标头

    我正在使用curl 与服务器通信 当我发出数据请求时 我收到 HTTP 标头 后跟由边界分隔的 jpeg 数据 如下所示 我需要解析出 边界字符串 内容长度 我已将传入数据复制到 char 数组 如下所示 static size t OnR
  • 重新加载更新的 javascript> 代码而不完全重新加载 html 页面

    我正在开发一个单页 Web 应用程序 它具有许多不同的功能和形式 当开发一个深度 我的意思是主页上没有的 功能时 我会经历这个循环 开发代码 编辑类和函数 刷新整个页面 一路点击 直到到达我需要测试的部分 有时加起来大约一分钟 测试新代码
  • 扩展(十进制,例如 400.1、401.4 等)HTTP 状态代码从何而来?

    我越来越多地看到十进制样式 HTTP 状态代码的激增 而且我似乎找不到任何 RFC 或其他 IETF 建议 甚至 W3C 草案或除 Microsoft IIS 文档之外的其他内容 请参阅https support microsoft com
  • Android httpclient文件上传数据损坏和超时问题

    我在 Android 中上传图像时遇到问题 我正在使用 apache httpmime 4 1 lib 代码是这样的 MultipartEntity reqEntity new MultipartEntity HttpMultipartMo

随机推荐

  • 计算机网络ip尽最大努力交付,计算机网络知识(IP、TCP、UDP)--持续更新

    互联网的两个重要的基本特点 连通性和共享 计算机网络由若干结点和连接这些结点的链路组成 互联网的组成 边缘部分 核心部分 网络边缘的端系统之间的通信可分为两大类 客户 服务器方式 C S方式 和对等方式 P2P方式 互联网的核心部分 许多网
  • 原始传奇手游服务器不显示,原始传奇手游为什么进不去 无法登录游戏解决方法...

    近日有一款由古力娜扎代言的手游 原始传奇 上线了 不少玩家也很想体验一番 可是却发现原始传奇手游进不去 不知道是为什么 下面悠小悠就为大家详细介绍下无法登录游戏的原因和解决方法 一起探讨下吧 原始传奇手游进不去原因及解决方法 1 如果是登录
  • tomcat没有日志输出--解决办法

    程序没有问题 只是控制台信息卡 感觉像程序休眠了一样 然后在控制台点backspace或是enter 程序恢复正常 控制台日志正常输出 静态文件访问可以 解决办法 转载于 https blog 51cto com 13693838 2398
  • BIND9的架构与机制笔记1

    BIND9采用的是事件驱动的机制来工作 而事件的源头则是IO IO在linux使用的EPOLL的边缘触发模式 本篇说的是epoll BIND9如果创建了watcher线程 宏USE WATCHER THREAD控制 这里就讨论有线程的情况
  • Redis第五讲 Redis内存淘汰策略之LRU与LFU算法详细介绍

    前面介绍了Redis的一些内存淘汰策略 一般比较常用的两种淘汰策略为LRU LFU 而且他们的算法考察的也比较多 LRU 最近最久未使用 标准LRU算法是这样的 它把数据存放在链表中按照 最近访问 的顺序排列 当某个key被访问时就将此ke
  • 机器学习——无监督学习

    机器学习的分类 一般分为下面几种类别 监督学习 supervised Learning 无监督学习 Unsupervised Learning 强化学习 Reinforcement Learning 增强学习 半监督学习 Semi supe
  • Vue 中实现 excel文件上传功能

    Duang 最近搭建了一个自己的博客小破站 欢迎各位小伙伴来访吖 ares coder blog portalhttps www ares stack cn blog service game 场景 上传excel表 并将excel表中的数
  • Django实现前后端分离开发

    前后端分离开发 在传统的Web应用开发中 大多数的程序员会将浏览器作为前后端的分界线 将浏览器中为用户进行页面展示的部分称之为前端 而将运行在服务器 为前端提供业务逻辑和数据准备的所有代码统称为后端 所谓前后端分离的开发 就是前后端工程师约
  • Hadoop 之上的数据建模 - Data Vault 2.0

    对比传统的基于 RDBMS 之上的数据仓库和商业智能项目 尝试着说说 Hadoop 之上的数据仓库 从ETL 数据存储 到分析展现 重点围绕数据建模方面做分析 因为这是本文的重点 介绍一份新的数据建模方式 Data Vault 2 0 ET
  • HTML框架构建

    HTML框架构建 1 划分框架 A 使用标签决定如何划分框架 必须要有标签设定每个小窗口的网页 该标签中有src属性为每个URL值指定一个HTML文件 这个文件必须事先做好 B 标签常用的属性 属性 描述 cols 用 像素数 或 分个左右
  • Android-PullToRefresh下拉刷新库基本用法

    PullToRefresh是一套实现非常好的下拉刷新库 它支持 ListView ExpandableListView GridView WebView ScrollView HorizontalScrollView ViewPager 等
  • AutoEncoder (自编码/非监督学习)

    神经网络也能进行非监督学习 只需要训练数据 不需要标签数据 自编码就是这样一种形式 自编码能自动分类数据 而且也能嵌套在半监督学习的上面 用少量的有标签样本和大量的无标签样本学习 这次我们还用 MNIST 手写数字数据来压缩再解压图片 然后
  • Boost升压电路调试

    背景 项目用到了一款升压电路 将12V升压到32V 电流要求有12A 最大18A 设计的方案是使用Boost Controller 外置MOS来实现 选定的Controller芯片为Maxim的MAX25203 问题 回板后进行调试 在不使
  • 硕士毕业论文应该如何梳理论文框架?

    硕士毕业论文相比于本科论文来说 具有更为广阔的知识面 对于研究的课题也更有深度 如果硕士毕业论文能取得一个很高的成绩 那么不管之后是继续求学还是找工作 都会有一定的优势 我曾经就硕士论文这方面和我的一个同学讨论过 当时我询问他是怎么取得69
  • React+React-Redux+Webpack+Express+MongoDB完整项目利用PM2+github部署到服务器

    React项目使用pm2部署上线 简述 项目概述 项目文件和代码结构 登录到服务器 输入指令 安装和配置nginx 安装MongoDB 打通三端 客户端 github 服务器 本地到github 服务器到github 本地到服务器 pm2部
  • 正大讲解什么叫国际期货?需要多少本金?

    国际期货是指交易所建立在中国大陆以外的期货交易 以美国 英国 新加坡等交易所内的产品为常见交易期货合约 有些期货合约品种会对国内期货价格变动产生影响 所以国内投资者可以参考国际期货行情进行期货交易 开户没有资金限制 但交易期货要交纳手续费和
  • 32 位的有符号整数的取值范围以及数值溢出

    short int long 是C语言中常用的三种整数类型 分别称为短整型 整型 长整型 在现代操作系统中 short int long 的长度分别是 2 4 4 或者 8 它们只能存储有限的数值 当数值过大或者过小时 超出的部分会被直接截
  • 关于在VM虚拟机下,安装OpenWrt软路由,所遇错误及解决方法。

    首先是去阿里的openwrt源下载的镜像为img格式 vm虚拟无法识别 需要转换为iso格式或者vmdk格式 用软碟通转换iso格式失败 于是准备转换成vmdk格式 网上大部分采用starwindconverter软件 但是最新的版本老是报
  • 数字水印

    数字水印 Digital Watermarking 1 技术是将一些标识信息 即数字水印 直接嵌入数字载体当中 包括多媒体 文档 软件等 或是间接表示 修改特定区域的结构 且不影响原载体的使用价值 也不容易被探知和再次修改 但可以被生产方识
  • Golang笔记:使用http包实现基础WebServer功能

    文章目录 目的 监听请求并响应 请求解析 进行响应 静态文件服务 总结 目的 WebServer是一种非常常用的功能 Golang的高并发特性在处理此类工作中也有较大的优势 同时借助标准库中的 net http 包可以非常快速的编写WebS