http库

2023-05-16

当我们使用 Go 语言进行 Web 开发时,不可避免地要使用到 http 包。该包提供了 HTTP 客户端和服务器的实现,可以轻松地编写 HTTP 服务器和客户端。在本节中,我们将学习如何使用 Go 语言中的 http 包来编写 Web 服务器和客户端。

基本使用

使用 http 包创建 Web 服务器很容易。下面是一个简单的 Web 服务器示例,它将响应客户端请求并返回 "Hello, World!":

package main

import (
	"fmt"
	"net/http"
)

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

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

该示例中,我们使用 http.HandleFunc() 函数将 URL 根路径 / 与一个匿名函数关联起来。当用户访问 URL 根路径时,该函数将被调用,并将 "Hello, World!" 响应写入响应流中。最后,我们使用 http.ListenAndServe() 函数来启动 Web 服务器,它会监听本地端口 8080 并处理传入的 HTTP 请求。在此示例中,我们将第二个参数 nil 传递给 http.ListenAndServe() 函数,这表示我们使用默认的 HTTP 处理程序来处理所有传入的 HTTP 请求。如果需要更复杂的路由,可以使用第二个参数传递一个 http.Handler 类型的参数。

HTTP 客户端

除了作为 Web 服务器的实现,Go 语言中的 http 包还提供了一个简单的 HTTP 客户端。下面是一个简单的 HTTP 客户端示例,它将向 http://example.com 发送 GET 请求并打印响应内容:

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

funcmain() {
	resp, err := http.Get("http://example.com")
	if err != nil {
		fmt.Println(err)
		return
	}

	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(body))
}

在该示例中,我们使用 http.Get() 函数来向 http://example.com 发送一个 GET 请求。该函数返回一个 *http.Response 类型的值 resp,其中包含响应的状态码、头部和响应正文。我们通过 ioutil.ReadAll() 函数从响应正文中读取响应内容,并使用 fmt.Println() 函数将其打印到控制台上。最后,我们通过 resp.Body.Close() 函数关闭响应正文的读取器

高级功能

重定向

Go的http包可以自动处理HTTP重定向。当客户端向服务器发送一个请求并且服务器返回一个重定向响应时,http包会自动发送另一个请求到重定向的URL上,并将响应返回给客户端。下面是一个简单的例子:

package main

import (
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/redirect", func(w http.ResponseWriter, r *http.Request) {
        http.Redirect(w, r, "https://www.example.com", http.StatusMovedPermanently)
    })

    srv := &http.Server{
        Addr:    ":8080",
        Handler: http.DefaultServeMux,
    }

    log.Fatal(srv.ListenAndServe())
}

这个例子中,我们通过http.HandleFunc函数来定义一个路由,即访问/redirect路径时,执行重定向功能。在处理函数中,我们调用了http.Redirect函数来实现重定向,其中第一个参数是ResponseWriter,第二个参数是Request,第三个参数是重定向的目标地址,第四个参数是HTTP状态码。这里我们使用了http.StatusMovedPermanently,即301状态码,表示永久性重定向。

接着我们创建了一个http.Server实例,设置监听地址为:8080,处理器使用默认的ServeMux,最后通过srv.ListenAndServe()启动服务。这里没有指定TLS证书和私钥,如果需要使用HTTPS协议,需要在http.Server中设置相关选项。

这个例子实现了一个非常简单的重定向功能,如果需要更复杂的重定向规则,可以使用一些第三方库,如gorilla/muxgo-chi/chi

Cookie

Cookie是一种在Web浏览器中存储数据的机制,可以用于识别用户、记录用户状态等。Go的http包提供了对Cookie的支持。可以使用http.Cookie结构体来创建、修改和删除Cookie。

package main

import (
	"fmt"
	"net/http"
)

func main() {
	// 设置Cookie
	http.HandleFunc("/set_cookie", func(w http.ResponseWriter, r *http.Request) {
		cookie := &http.Cookie{
			Name:   "username",
			Value:  "test",
			MaxAge: 3600,
			Path:   "/",
		}
		http.SetCookie(w, cookie)
		fmt.Fprintln(w, "Cookie set successfully!")
	})

	// 读取Cookie
	http.HandleFunc("/get_cookie", func(w http.ResponseWriter, r *http.Request) {
		cookie, err := r.Cookie("username")
		if err != nil {
			fmt.Fprintln(w, "Cookie not found!")
			return
		}
		fmt.Fprintf(w, "Cookie found: %s=%s", cookie.Name, cookie.Value)
	})

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

在这个例子中,我们创建了一个名为“username”的Cookie,并将其值设置为“test”。我们还设置了Cookie的最大生存时间为3600秒,以及路径为“/”,表示可以在整个网站中访问此Cookie。

我们还定义了两个路由处理程序,“/set_cookie”和“/get_cookie”,分别用于设置和读取Cookie。在“/set_cookie”处理程序中,我们使用http.SetCookie函数将Cookie写入响应头部。在“/get_cookie”处理程序中,我们使用r.Cookie函数来读取Cookie。

上传文件

Go的http包可以方便地处理文件上传。下面是一个简单的文件上传例子:

package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
    "path/filepath"
    "time"
)

const (
    UploadDir = "./upload" // 上传目录
)

func main() {
    http.HandleFunc("/", uploadHandler)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        fmt.Println(err)
    }
}

func uploadHandler(w http.ResponseWriter, r *http.Request) {
    switch r.Method {
    case http.MethodGet:
        http.ServeFile(w, r, "./index.html")
    case http.MethodPost:
        file, header, err := r.FormFile("file")
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        defer file.Close()

        // 创建上传目录
        if _, err := os.Stat(UploadDir); os.IsNotExist(err) {
            os.Mkdir(UploadDir, os.ModePerm)
        }

        // 创建保存文件
        fileName := fmt.Sprintf("%d_%s", time.Now().Unix(), header.Filename)
        filePath := filepath.Join(UploadDir, fileName)
        newFile, err := os.Create(filePath)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        defer newFile.Close()

        // 复制文件
        if _, err := io.Copy(newFile, file); err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }

        fmt.Fprintln(w, "Upload successful!")
    }
}

该示例中,我们首先定义了上传目录,然后在 uploadHandler 中,判断请求方法是否为 POST,如果是,则解析上传的文件,创建上传目录(如果不存在),然后创建新文件,将上传文件内容写入新文件中。

其中,我们使用了 Golang 的标准库 net/http 中的 ServeFile 函数,它会自动读取指定的文件,并将其内容发送给客户端。此外,还使用了 FormFile 函数解析上传的文件,os 包中的 Create 函数创建新文件,io.Copy 函数将上传文件内容复制到新文件中。

在这个示例中,我们只是简单地将上传文件写入文件系统。在实际的生产环境中,你可能需要更多的验证和处理,例如验证上传文件的类型和大小,限制上传文件的数量,以及将上传的文件保存到分布式存储等。

采用 HTTP/2 协议,实现HTTP服务器

package main

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

func main() {
    // 创建路由
    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Welcome to my website!")
    })

    // 创建TLS证书和密钥
    cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
    if err != nil {
        log.Fatal(err)
    }

    // 创建TLS配置
    tlsConfig := &tls.Config{
        Certificates: []tls.Certificate{cert},
        NextProtos:   []string{"h2", "http/1.1"},
    }

    // 创建HTTP/2服务器
    server := &http.Server{
        Addr:      ":443",
        Handler:   mux,
        TLSConfig: tlsConfig,
    }

    // 启动HTTP/2服务器
    log.Fatal(server.ListenAndServeTLS("", ""))
}

在上面的代码中,我们首先创建了一个路由,然后使用TLS证书和密钥创建了一个TLS配置。接着,我们创建了一个HTTP/2服务器,并将路由和TLS配置添加到服务器中。最后,我们使用TLS证书和密钥启动了服务器

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

http库 的相关文章

  • 使用 .htaccess 在 HTTP 和 HTTPS 之间正确切换

    我们有一个购物网站 托管在共享主机 Mediatemple Gridserver 上 网站的某些部分需要使用 HTTPS 结帐等 但其余部分应使用 HTTP 有谁知道我们如何始终强制对特定 URL 正确使用 HTTP HTTPS 我们已经让
  • 如何用 Java 以编程方式下载网页

    我希望能够获取网页的 html 并将其保存到String 这样我就可以对其进行一些处理 另外 我如何处理各种类型的压缩 我将如何使用 Java 来做到这一点 我会使用像样的 HTML 解析器Jsoup http jsoup org 那么就很
  • 如何从 apache 中删除日期标头?

    我需要最小化 Apache HTTP 响应标头 现在我将它们减少如下 HTTP 1 1 200 OK Date Thu 25 Mar 2010 21 57 41 GMT Server Apache Content Type text htm
  • 多个资源的 REST 接口使用

    我目前正在通过 http 添加 REST API 到在线服务 我遇到了一个非常简单的问题 我找不到令我满意的答案 我主要有 2 个资源 用户 和 报告 正如您所猜测的那样 报告与用户相关联 与一个且仅一个 我的数据库中的外键 不管怎样 我有
  • 如何设置http请求的源IP?

    在发送 http 请求之前 我需要设置源 IP 地址 用于 IP 欺骗等 用于建立http连接的类是HTTPURLConnection 我在 stackoverflow 上找到了下面的链接 这非常有用 注册和使用自定义 java net U
  • IIS7 和 HTTP 状态代码处理

    我因试图对 IIS7 集成模式 中的错误呈现进行完整的编程控制而感到非常头疼 我想要做的是给出一个错误 找不到页面 内部服务器错误 未经过身份验证等 将整个请求传输到自定义 ASPX 或 HTML 我更喜欢后者 并使用正确的 HTTP 状态
  • 文件下载时文件名损坏 (IE)

    我实现了一个简单的文件上传下载机制 当用户单击文件名时 将下载带有以下 HTTP 标头的文件 HTTP 1 1 200 OK Date Tue 30 Sep 2008 14 00 39 GMT Server Microsoft IIS 6
  • 如何在 ASP.NET Core 控制器中接收“multipart/mixed”

    旧系统会向我发送以下内容 POST xml HTTP 1 1 Host localhost 9000 User Agent curl 7 64 1 Accept Content Length 321 Content Type multipa
  • Nestjs拦截并修改传出的http请求

    所以我可能错过了一些东西或者做错了一些事情 我有一个 NestJS 应用程序正在尝试向外部 API 发出 http 请求 我希望能够拦截此传出请求并在执行之前修改其标头 我尝试使用拦截器 但没有成功 传入的 http 请求被拦截 但传出的请
  • 角度 $q.all() 是否有第二次成功,如 jQuery $.get()

    查看 jQuery 文档 我发现了以下内容 get example php function alert success done function alert second success lt fail function alert e
  • 如何为 HTTP GET 的多个 Key-Value 参数设计 REST URI

    我正在设计一个 RESTful API 一项服务应该提供多个键值对的查询功能 例如 客户端可以使用一个 HTTP GET 请求来查询不同的产品及其关联的数量 客户想要查询金额为 44 的产品 1 和金额为 55 的产品 2 我实际上不希望我
  • 即使禁用缓存,Safari 也会缓存 GET 请求

    我已经将我所知道的所有标头设置为在我的服务器上禁用缓存 甚至禁用 ETAG 但 Safari 仍然偶尔 大约 50 次 缓存我的请求 Workflow 我正在实施 oauth 1 所以 浏览器使GET api user request 服务
  • C# HttpWebRequest 服务器未返回完整响应

    我正在向返回带有数据的 HTML 的服务器发出 HTTP 请求 但有时它会 停在中间 没有任何明确的解释 例如响应结束 Content length 14336 chars p p br ul ul example com var auth
  • IE 下的 Http 请求速度变慢

    在我的 javascript 应用程序中工作时 我注意到使用 IE 11 时 相同的 ajax 请求时间最多延长 10 倍 响应大小完全相同 12 6KB 我看到的唯一区别是 IE 添加 Pragma no cache 不是铬 Chrome
  • 我应该如何处理 Android 应用程序中 http post 的服务器超时和错误代码响应?

    我的 Android 应用程序会向 URL 发送 http 帖子 例如http example com 电子邮件受保护 http example com abc php email abc xyz com因此 Android 应用程序基本上
  • RxJS Angular2 在 Observable.forkjoin 中处理 404

    我目前正在链接一堆 http 请求 但是在订阅之前我无法处理 404 错误 My code 在模板中 service getData subscribe data gt this items data err gt console log
  • 使用PHP获取http url参数而不自动解码

    我有一个像这样的网址 test php x hello world y 00h 00e 00l 00l 00o 当我将它写入文件时 file put contents x txt GET x gt hello world file put
  • Http Auth 不适用于 PHP

    我使用 Laravel Lumen Shield 扩展进行 Http 身份验证 但是在我的本地计算机上一切都很完美 我只在我们的服务器上遇到了问题 问题是在我提交正确的登录数据后 登录屏幕再次出现 我尝试了不同的登录数据 不同的浏览器 登录
  • TRESTRequest:是否可以在 POST 请求中使用自定义媒体类型?

    例如 我们有一个 API 需要我们自己的供应商特定内容类型application vnd xxxx custom custom data json但查看 REST Client 的源代码 它似乎总是默认为 REST Types 中的 Con
  • 使用矩阵参数创建 GET 请求

    我将使用的网络服务需要矩阵参数 http tester com v1 customers lastname Jackson firstname Tim bookingreference 7Y9UIY 而不是通常的 http tester c

随机推荐

  • C/C++基础 C语言预编译宏__LINE__、__FILE__、__DATE__、__TIME__、__FUNCTION__

    ANSIC标准定义了以下6种可供C语言使用的预定义宏 xff1a LINE 在源代码中插入当前源代码行号 FILE 在源代码中插入当前源代码文件名 DATE 在源代码中插入当前编译日期 注意和当前系统日期区别开来 TIME 在源代码中插入当
  • linux下每次git clone不需输入账号密码的方法

    有的仓库有很多的子模块 submodule 当clone的时候每个子模块都会让输入一次账户密码 xff0c 不胜其烦 xff0c 解决方法如下 xff1a 在 下 xff0c touch创建文件 git credentials 用vim编辑
  • Ubuntu创建新用户的两种方法

    组里的服务器是Ubuntu系统 xff0c 跑实验的话需要远程访问 xff0c 这样的话需要在服务器上创建一个自己的账户 xff0c 本文记录一下在Ubuntu系统下创建新用户的过程 xff08 服务器的远程访问一般通过ssh来实现 xff
  • Ubuntu中gnome-terminal的使用

    基本使用 gnome terminal命令用于打开一个新的终端 xff0c 直接在命令行就可以打开一个新的终端 gnome terminal 打开后自动最大化 gnome terminal maximize 打开后全屏 gnome term
  • 【计算机基础】字节序

    字节序 计算机最小的存储单位是 位 xff08 Bit xff09 xff0c 但是 xff0c 计算机中最基本的存储单位是字节 xff08 Byte xff09 1 Byte 61 8 Bit 计算机在存储大于1字节的数据时 xff0c
  • 内存中堆和栈的区别

    在说堆和栈之前 xff0c 我们先说一下JVM xff08 虚拟机 xff09 内存的划分 xff1a Java程序在运行时都要开辟空间 xff0c 任何软件在运行时都要在内存中开辟空间 xff0c Java虚拟机运行时也是要开辟空间的 J
  • 1.5 万字 + 40 张图解 HTTP 常见面试题(值得收藏)

    作者 xff1a 小林coding 图解计算机基础网站 xff1a https xiaolincoding com 大家好 xff0c 我是小林 xff0c 我最开始写的第一篇图解文章就是这篇 xff1a 那时候我也就不到 100 读者 x
  • libcurl第七课 multipart/formdata表单使用

    场景 multipart form data是浏览器用表单上传文件的方式 最常见的情境是 xff1a 在写邮件时 xff0c 向邮件后添加附件 xff0c 附件通常使用表单添加 xff0c 也就是用multipart form data格式
  • 【测绘专用】中海达全站仪数据导入南方CASS

    先从全站仪导入数据到电脑 xff08 我是用U盘的 xff09 xff0c 然后打开数据文件后是这个样子 上图并不是导出后原先的数据格式 导出文件后 xff0c 它的数据格式实际上不是上面这样的 xff0c 要经过处理后才行 从中海达下载数
  • 广工 AnyviewC 数据结构习题 第二章

    广工 AnyviewC 数据结构习题 第二章 广工 AnyviewC 数据结构习题 第二章Anyview 数据结构 第二章1 题目 试写一算法 xff0c 实现顺序栈的判空操作2 题目 试写一算法 xff0c 实现顺序栈的取栈顶元素操作3
  • 广工 AnyviewC C语言习题 第六章

    Anyview 第六章 6 022 n是系统给定的外部变量 编写程序 xff0c 求1到n间的 自然数之和 请定义局部变量s存放求和的结果 xff0c 并用下 列语句输出结果 span class token function printf
  • 广工 AnyviewC C语言习题 第七章

    Anyview 第七章 习题7 010 写一函数求3个整数中最小的数 span class token keyword int span span class token function min span span class token
  • 广工 AnyviewC C语言习题 第十、十一章

    Anyview 第十 十一章 第十章 10 011 请编写一个函数func char s char t int n xff0c 由数组s中长度为n的字符序列构造其逆序列 xff0c 并存储在数组t中 例如 xff0c 由给定字符序列s 61
  • 【测绘专用】 MATLAB 四叉树分割遥感图像

    MATLAB 四叉树分割遥感图像 四叉树是遥感图像处理里面常用的一种算法 xff0c 我这里采用递归的方法来实现 数据处理的思路 对于图像矩阵 xff0c 我是判断它的方差是否小于某个阈值 xff0c 大于就继续分 xff0c 小于就不分
  • VS code配置latex美赛模板

    VS code配置latex美赛模板 首先要知道安装的latex版本是miktex还是texlive Miktex 我的是2 9的 解压模板文件 xff1a 用VScode打开上面红圈里的文件即可进行编辑 Texlive 打开 Tex Li
  • OkHttpUtils (OkHttpUtil工具类)

    public class OkHttpUtil static OkHttpUtil okHttpUtil private OkHttpClient Builder builder private Request Builder reques
  • C++经典类库(C++开发必看)

    现实中 xff0c C 43 43 的库门类繁多 xff0c 解决的问题也是极其广泛 xff0c 库从轻量级到重量级的都有 本文为你介绍了十一种类库 xff0c 有我们常见的 xff0c 也有不常见的 xff0c 一起来看 AD xff1a
  • libcurl第九课 Content-Length的添加机制

    场景 lt DOCTYPE HTML PUBLIC 34 W3C DTD HTML 4 01 EN 34 34 http www w3 org TR html4 strict dtd 34 gt lt HTML gt lt HEAD gt
  • 英伟达NX上使用 Python 硬解码ip摄像头h264视频流

    问题 用另一篇博客rtsp拉流的方法 xff0c 当单独拉流时 xff0c 不会出现任何问题 可是如果将拉流和检测算法结合 xff0c 就会出现断流 xff0c 花屏 xff0c 跳帧 xff0c 播放延迟 xff0c 播放速度卡顿等问题
  • http库

    当我们使用 Go 语言进行 Web 开发时 xff0c 不可避免地要使用到 http 包 该包提供了 HTTP 客户端和服务器的实现 xff0c 可以轻松地编写 HTTP 服务器和客户端 在本节中 xff0c 我们将学习如何使用 Go 语言