Original author, public number [programmer reading], welcome to pay attention to the public number, reprint the article please indicate the source oh.

In a Web application, every HTTP transaction consists of a Request and a Response, and this time we’ll talk about how Go handles data responses in the Web.

If you want to know how Go handles Web requests, you can refer to my other article “How Do Go Web Handle Web Requests?” .

Web Data Response

The response structure of the Web is similar to that of the request. The response is divided into three parts: the response line, the response header, and the response body.

  1. Response line: protocol, response status code, and status description, for example, HTTP/1.1 200 OK
  2. Response header: Contains various header fields, such as cookie and Content-Type.
  3. Response body: Carries the data the client wants, formatted and encoded according to the content-Type of the header.

The response status code has fixed values and meanings:

  • 100 to 199: indicates that the server receives the request successfully. The client must submit the next request to complete the processing.
  • 200 to 299: indicates that the server receives the request successfully and the processing is complete. The most common is 200
  • 300 to 399: The client needs to further refine the request to complete the request. For example, if the resource requested by the client has been moved to a new address, use 302 to redirect the resource. If the resource requested by the client has not changed, use 304 to tell the client to obtain the resource from the local cache.
  • 400 to 499: An error occurs in the request from the client. For example, 404 indicates that the requested resource cannot be found on the Web server. 403 indicates that the server rejects the access from the client.
  • 500 to 599: An error occurs on the server. The most common value is 500

Go handles Web data responses

Go encapsulates the HTTP response in the http.ResponseWriter structure, which is simply defined as three methods.

ResponseWriter

In the NET/HTTP source package, the structure information for http.ResponseWriter is defined as follows:

typeResponseWriter interface {Header() Header // Header Write([]byte) (int, error) // WriteHeader(statusCode int)// statusCode}Copy the code
1. The Header method

The header method returns an HTTP. header structure, which is used to set the response header information. The HTTP. header data type map is defined as follows:

type Header map[string][]string
Copy the code

The list of http.Header methods is as follows:

type Header
    func (h Header) Add(key, value string)
    func (h Header) Del(key string)
    func (h Header) Get(key string) string
    func (h Header) Set(key, value string)
    func (h Header) Write(w io.Writer) error
    func (h Header) WriteSubset(w io.Writer, exclude map[string]bool) error
Copy the code
2. The Writer () method

The Write method is defined as follows and is used to return data streams to clients. It is the same as the Write method in IO.Writer and is a standard method in Go.

Write([]byte) (int, error)
Copy the code
3. WriterHeader method

The writerHeader method is defined as follows:

WriteHeader(statusCode int)
Copy the code

The statusCode parameter represents the response code, which can be a constant value defined in the HTTP package:

Const (StatusContinue = 100, 6.2.1 StatusSwitchingProtocols = 101, 6.2.2 StatusProcessing = 102 // RFC 2518, 10.1 StatusOK = 200 // RFC 7231, 6.3.1 StatusCreated = 201 // RFC 7231, 6.3.2 StatusAccepted = 202 / / RFC 7231, 6.3.3 StatusNonAuthoritativeInfo = 203 / / RFC 7231, 6.3.4 StatusNoContent = 204 // RFC 7231, 6.3.5 StatusResetContent = 205 // RFC 7231, 6.3.6 StatusPartialContent = 206 // RFC 7233, 4.1 StatusMultiStatus = 207 // RFC 4918, Reported = 208 // RFC 5842, 2.1 StatusIMUsed = 226 // RFC 3229, 6.4.1 StatusMultipleChoices = 300 // RFC 7231, 6.4.1 StatusMovedPermanently = 301 // RFC 7231, 6.4.2 StatusFound = 302 // RFC 7231, 6.4.3 StatusSeeOther = 303 // RFC 7231, 6.4.4 StatusNotModified = 304 // RFC 7232, 4.1 StatusUseProxy = 305 // RFC 7231, 6.4.5 StatusTemporaryRedirect = 307 // RFC 7231, 6.4.7 StatusPermanentRedirect = 308 // RFC 7538, 3 StatusBadRequest = 400 // RFC 7231, 6.5.1 StatusUnauthorized = 401 // RFC 7235, 3.1 StatusPaymentRequired = 402 // RFC 7231, 6.5.2 StatusForbidden = 403 / RFC 7231, 6.5.3 StatusNotFound = 404 // RFC 7231, StatusNotAcceptable = 406 // RFC 7231, 6.5.6 StatusProxyAuthRequired = 407 // RFC 7235, 3.2 StatusRequestTimeout = 408 // RFC 7231, 6.5.7 StatusConflict = 409 // RFC 7231, 6.5.8 StatusGone = 410 // RFC 7231, 6.5.9 StatusPreconditionFailed = 412 // RFC 7201, 6.5.10 StatusPreconditionFailed = 412 // RFC 7201, 4.2 StatusRequestEntityTooLarge = 413 / / RFC 7231, 6.5.11 StatusRequestURITooLong = 414 / / RFC 7231, 6.5.12 StatusUnsupportedMediaType = 415 / / RFC 7231, 6.5.13 StatusRequestedRangeNotSatisfiable = 416 / / RFC 7233, StatusExpectationFailed = expectationfailed // RFC 791, expectationfailed = expectationfailed // RFC 791, 2.3.3 StatusMisdirectedRequest = 421 / / RFC 7540, 9.1.2 StatusUnprocessableEntity = 422 / / RFC 4918, 11.statuslocked = 423 // RFC locked, 11.statusfailedDependency = 424 // RFC failedDependency = 424, 11.4 StatusTooEarly = 425 // RFC 8470, 5.2. StatusUpgradeRequired = 426 // RFC 7231, 6.5.15 StatusPreconditionRequired = 428 / / RFC 6585, 3 StatusTooManyRequests = 429 / / RFC 6585, 4 StatusRequestHeaderFieldsTooLarge = 431 // RFC 6585, 5 StatusUnavailableForLegalReasons = 451 // RFC 7725, 3 StatusInternalServerError = 500 / / RFC 7231, 6.6.1 StatusNotImplemented = 501 / / RFC 7231, 6.6.2 StatusBadGateway = 502 // RFC 7231, 6.6.3 StatusServiceUnavailable = 503 // RFC 7231, 6.6.4 StatusGatewayTimeout = 504 / / RFC 7231, 6.6.5 StatusHTTPVersionNotSupported = 505 / / RFC 7231, 6.6.6 StatusVariantAlsoNegotiates = 506 / / RFC 2295, 8.1 StatusInsufficientStorage = 507 / / RFC 4918, 7 StatusLoopDetected = 89 // RFC 5842, 7 STATusnotexglen = 89 // RFC 2774, 7 StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6 )Copy the code
Example 4.
package main
import (
	"fmt"
	"net/http"
)
func main() {
    http.HandleFunc("/test", func(writer http.ResponseWriter, request *http.Request) {
        header := writer.Header()
        header.Add("Content-Type"."application/json")
        writer.WriteHeader(http.StatusBadGateway)
        fmt.Fprintln(writer,"Web response")
    })
    http.ListenAndServe(": 8080",nil)
}
Copy the code

View the results on Network in the browser console:

Cookie

Note the difference between Cookie and Session. Cookie uses the server to store certain information to the client to identify the user. It is a user tracking mechanism, while Session is a mechanism for the server to maintain the Session between multiple requests. The two can be used together or independently.

The NET/HTTP package provides SetCookie methods for writing cookies to clients.

func SetCookie(w ResponseWriter, cookie *Cookie)
Copy the code

The first parameter is the ResponseWriter structure, and the second parameter is the Cookie structure, which is defined as follows:

typeCookie struct { Name string Value string Path string // optional Domain string // optional Expires time.Time // optional  RawExpires string //for reading cookies only

    // MaxAge=0 means no 'Max-Age' attribute specified.
    // MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'
    // MaxAge>0 means Max-Age attribute present and given inSeconds MaxAge int Secure bool HttpOnly bool SameSite SameSite // Go 1.11 Raw string Unparsed []string // Raw text of unparsed attribute-value pairs }Copy the code
The sample
package main

import (
	"net/http"
	"time"
)

func main() {
    http.HandleFunc("/test", func(writer http.ResponseWriter, Request * http.request) {expire := time.now () expire.adddate (0,0,3) cookie := & http.cookie {Name:"Auth",Value:"test",Expires:expire}
        http.SetCookie(writer,cookie)
    })
    http.ListenAndServe(": 8080",nil)
}
Copy the code

The results

JSON response

The Go library does not encapsulate a way to respond to JSON data directly to the client, but it is easy to encapsulate one yourself, using the Encoding/JSON package Encoder structure to write JSON data to the response stream.

The sample
package main

import (
    "encoding/json"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/profile", func(writer http.ResponseWriter, request *http.Request) {
        data := map[string]string{
            "username": "Xiao Ming"."email":    "[email protected]",
        }
        err := JSON(writer, data)
        check(err)
    })
    http.ListenAndServe(": 8080", nil)
}

func check(err error) {
    iferr ! = nil { log.Fatal(err) } } func JSON(w http.ResponseWriter, data interface{}) error { w.Header().Set("Content-Type"."application/json")
	encoder := json.NewEncoder(w)
	return encoder.Encode(data)
}
Copy the code

HTML template

Although under the general trend of the separation of the front and back ends, the back end development is more to return data to the front end in the way of INTERFACE API response JSON, but there are still some simple business, is by the back end directly return HTML template by the browser, by the browser rendering.

The Go language renders HTML templates using the HTML/Template package.

The sample
package main

import (
    "html/template"
    "log"
    "net/http") const tpl = ` <! DOCTYPE html> <html> <head> <meta charset="UTF-8">
		<title>{{.Title}}</title>
	</head>
	<body>
		{{range .Items}}<div>{{ . }}</div>{{else}}<div><strong>no rows</strong></div>{{end}}
	</body>
</html>`

func main() {

    t, err := template.New("webpage").Parse(tpl)
    check(err)

    data := struct {
        Title string
        Items []string
    }{
    Title: "My first HTML page.",
    Items: []string{
            "My Album."."My Blog",
        },
    }

    http.HandleFunc("/profile", func(writer http.ResponseWriter, request *http.Request) {
        err = t.Execute(writer, data)
        check(err)
    })
    http.ListenAndServe(": 8080", nil)
}

func check(err error) {
    iferr ! = nil { log.Fatal(err) } }Copy the code

summary

Go language provides a good support for Web development in NET/HTTP package, allowing developers to use Go for Web application development, almost no need to use any Web framework, then can complete the business logic development work.


Your attention is the biggest encouragement on my writing road!