Оригинальный автор, публичный аккаунт [программист чтение], прошу обратить внимание на паблик-аккаунт, просьба указывать источник перепечатываемой статьи.
В веб-приложении каждая HTTP-транзакция состоит из запроса (Request) и ответа (Response), на этот раз мы поговорим о том, как Go обрабатывает ответы данных в Интернете.
Если вы хотите узнать, как Go обрабатывает веб-запросы, вы можете обратиться к другой моей статье.Как Go Web обрабатывает веб-запросы?.
ответ веб-данных
Структура ответа сети аналогична структуре запроса.Ответ разделен на три части: строка ответа, заголовок ответа и тело ответа.
- Строка ответа: протокол, код состояния ответа и описание состояния, например: HTTP/1.1 200 OK
- Заголовок ответа: содержит различную информацию о полях заголовка, такую как cookie, Content-Type и другую информацию заголовка.
- Тело ответа: Содержит данные, которые хочет клиент Формат и кодировка определяются Content-Type заголовка.
Код состояния ответа имеет фиксированное значение и значение:
- 100~199: указывает, что сервер успешно получил запрос от клиента и требует, чтобы клиент продолжал отправлять следующий запрос для завершения всего процесса обработки.
- 200~299: указывает, что сервер успешно получил запрос и завершил весь процесс обработки. Самый распространенный: 200
- 300~399: чтобы выполнить запрос, клиент должен уточнить запрос. Обычно используется, например: ресурс, запрошенный клиентом, перемещен на новый адрес, используйте 302, чтобы указать, что ресурс перенаправлен, а ресурс, запрошенный клиентом, не изменился, используйте 304, чтобы сообщить клиенту, чтобы он получил его от локальный кеш.
- 400~499: В запросе клиента есть ошибка, например: 404 означает, что запрошенный вами ресурс не может быть найден на веб-сервере, 403 означает, что сервер отказывает клиенту в доступе, как правило, недостаточно прав.
- 500~599: Произошла ошибка на стороне сервера, чаще всего используется: 500
Go обрабатывает ответы веб-данных
Go инкапсулирует http-ответ в структуру http.ResponseWriter.Определение ResponseWriter очень простое, всего три метода.
ResponseWriter
В исходном пакете net/http информация о структуре http.ResponseWriter определяется следующим образом:
type ResponseWriter interface {
Header() Header //头部
Write([]byte) (int, error) //写入方法
WriteHeader(statusCode int)//状态码
}
1. Метод заголовка
Метод заголовка возвращает структуру http.Header, которая используется для установки информации заголовка ответа.Карта типов данных http.Header определяется следующим образом:
type Header map[string][]string
Список методов http.Header выглядит следующим образом:
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
2. Метод Writer()
Метод Write определяется следующим образом, который используется для возврата потока данных клиенту, что согласуется с определением метода записи в io.Writer и является стандартным методом в потоке ввода-вывода языка Go.
Write([]byte) (int, error)
3. Метод WriterHeader
Определение метода WriterHeader выглядит следующим образом:
WriteHeader(statusCode int)
Параметр statusCode представляет собой код ответа, и его значение может быть постоянным значением, уже определенным в пакете http:
const (
StatusContinue = 100 // RFC 7231, 6.2.1
StatusSwitchingProtocols = 101 // RFC 7231, 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, 11.1
StatusAlreadyReported = 208 // RFC 5842, 7.1
StatusIMUsed = 226 // RFC 3229, 10.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, 6.5.4
StatusMethodNotAllowed = 405 // RFC 7231, 6.5.5
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
StatusLengthRequired = 411 // RFC 7231, 6.5.10
StatusPreconditionFailed = 412 // RFC 7232, 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, 4.4
StatusExpectationFailed = 417 // RFC 7231, 6.5.14
StatusTeapot = 418 // RFC 7168, 2.3.3
StatusMisdirectedRequest = 421 // RFC 7540, 9.1.2
StatusUnprocessableEntity = 422 // RFC 4918, 11.2
StatusLocked = 423 // RFC 4918, 11.3
StatusFailedDependency = 424 // RFC 4918, 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, 11.5
StatusLoopDetected = 508 // RFC 5842, 7.2
StatusNotExtended = 510 // RFC 2774, 7
StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6
)
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响应")
})
http.ListenAndServe(":8080",nil)
}
Просмотрите результаты выполнения в сети консоли браузера:
Cookie
Обратите внимание на разницу между Cookie и Session.Cookie использует сервер для сохранения некоторой информации клиенту, которая используется для идентификации пользователей, механизма отслеживания пользователей, а Session - это механизм для сервера для поддержания сеанса между несколькими запросами пользователей. ., оба могут использоваться вместе или независимо друг от друга.
Пакет net/http предоставляет метод SetCookie для записи файлов cookie клиенту.
func SetCookie(w ResponseWriter, cookie *Cookie)
Первый параметр — это структура ResponseWriter, а второй параметр — это структура Cookie, которая определяется следующим образом:
type Cookie 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 in seconds
MaxAge int
Secure bool
HttpOnly bool
SameSite SameSite // Go 1.11
Raw string
Unparsed []string // Raw text of unparsed attribute-value pairs
}
Пример
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)
}
результат операции
JSON-ответ
Стандартная библиотека Go не инкапсулирует метод для прямого ответа клиенту на данные JSON, однако его очень просто инкапсулировать самостоятельно.Вы можете использовать структуру Encoder пакета encoding/json для записи данных JSON в данные ответа. ручей.
Пример
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": "小明",
"email": "xiaoming@163.com",
}
err := JSON(writer, data)
check(err)
})
http.ListenAndServe(":8080", nil)
}
func check(err error) {
if err != 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)
}
HTML-шаблон
Несмотря на общую тенденцию разделения фронтенда и бекенда, бэкенд-разработка чаще используется для возврата данных во фронтенд в виде интерфейса API ответа JSON, но есть еще несколько простых бизнесов, бэкенд непосредственно возвращает шаблон HTML в браузер и визуализацию в браузере.
Язык Go может отображать шаблоны HTML с помощью пакета html/template.
Пример
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: "我的第一个HTML页面",
Items: []string{
"我的相册",
"我的博客",
},
}
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) {
if err != nil {
log.Fatal(err)
}
}
резюме
Язык Go обеспечивает хорошую поддержку веб-разработки в пакете net/http, позволяя разработчикам выполнять работу по разработке бизнес-логики без использования какой-либо веб-инфраструктуры при использовании Go для разработки веб-приложений.
Ваше внимание — самое большое поощрение на моем писательском пути!