背景 链接到标题

之前提供了一个用于下载文件的 API,使用到了 Content-Length 字段并踩了个坑: Content-Length 与实际的数据大小不一致。今天来学习下这个字段相关的知识。

Content-Length 链接到标题

Content-Length 是一个实体消息首部,用来指明发送给接收方的消息主体的大小,即用十进制数字表示的八位元组的数目。

当客户端向服务器发送一个请求时,服务器可以很清楚的知道内容大小,然后通过Content-length消息首部字段告诉客户端需要接收多少数据。除了使用 Transfer-Encoding,当Content-Length 存在是必须与实际传输的数据大小一致,如果前者大,则会导致请求一直等待直至超时;如果后者大,则会导致数据被截断,在最近版本的 Chrome 中,会直接提示 net::ERR_CONTENT_LENGTH_MISMATCH 报错导致加载失败。

package main

import (
	"net/http"
)

func main() {

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

		w.Header().Set("Content-Length", "20")
		//w.Header().Set("Content-Length", "12")
		w.WriteHeader(200)
		w.Write([]byte("hello world\n"))

	})

	http.ListenAndServe(":8080", nil)
}
Request URL: http://127.0.0.1:8080/
Request Method: GET
Status Code: 200 OK
Remote Address: 127.0.0.1:8080
Referrer Policy: no-referrer-when-downgrade
Content-Length: 12
Content-Type: text/plain; charset=utf-8
Date: Fri, 07 Feb 2020 14:36:40 GMT
X-DNS-Prefetch-Control: off

Transfer-Encoding 链接到标题

Transfer-Encoding 消息首部指明了将 entity 安全传递给用户所采用的编码形式。Transfer-Encoding 是一个逐跳传输消息首部,即仅应用于两个节点之间的消息传递,而不是所请求的资源本身。一个多节点连接中的每一段都可以应用不同的Transfer-Encoding 值。

如果在传输前不知道消息大小,那么就可以使用 Transfer-Encoding 。当设置了 Transfer-EncodingContent-Length 会被忽略,两者无法共存。

package main

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

// hello world, the web server
func HelloServer(w http.ResponseWriter, req *http.Request) {
        w.WriteHeader(200)
        for i := 0; i < 5; i++ {
                io.WriteString(w, "hello, world!\n")
                w.(http.Flusher).Flush()
        }
}

func main() {
        http.HandleFunc("/", HelloServer)
        err := http.ListenAndServe(":8080", nil)
        if err != nil {
                log.Fatal("ListenAndServe: ", err)
        }
}
Request URL: http://127.0.0.1:8080/
Request Method: GET
Status Code: 200 OK
Remote Address: 127.0.0.1:8080
Referrer Policy: no-referrer-when-downgrade
Content-Type: text/plain; charset=utf-8
Date: Fri, 07 Feb 2020 13:56:54 GMT
Transfer-Encoding: chunked
X-DNS-Prefetch-Control: off

参考链接 链接到标题