以后会开一个板块,摸鱼快报,快速记录这几周开发中雕虫小技。
前端使用Create React App脚手架,默认以localhost:3000端口启动;
后端使用golang-gin框架,使用8034端口启动。
登录模块走的是sso,前后端分离,后端需要向前端写入认证cookie
c.SetSameSite(http.SameSiteLaxMode)
c.SetCookie("userInfo", userInfoMapString, 60*60*12, "/", cfg.CookieDomain, false, false)
c.SetCookie("access_token", accessToken.(string), 60*60*12, "/", cfg.CookieDomain, false, false)
若种植cookie时设置domain=localhost:3000
,实际会发现该cookie被种为domain=localhost
① golang给出日志提示:2023/01/12 19:10:48 net/http: invalid Cookie.Domain "localhost:3000"; dropping domain attribute
, 该cookie domain被丢弃:
② 如果该cookie没有domain,该Cookie称之为HostOnly Cookie,后续请求只有host与cookie的domain完全相等,才能携带这个cookie。
react配置后端地址,要配置为
localhost:8034
,而不能是127.0.0.1:8034
经此一役:
golang net/http httpclient
Timeout
:
Timeout specifies a time limit for requests made by this Client. The timeout includes connection time, any redirects, and reading the response body. The timer remains running after Get, Head, Post, or Do return and will interrupt reading of the Response.Body.
HttpClient Timeout包括连接、重定向(如果有)、从Response Body读取的时间,内置定时器会在Get,Head、Post、Do 方法之后继续运行,并有能力中断读取Response.Body.
如果upstream服务器处理超时(upstream_response_time> client设置的timeout),则会返回context deadline exceeded (Client.Timeout exceeded while awaiting headers)
如果客户端使用io.ReadAll读取body超时,则会返回context deadline exceeded (Client.Timeout or context cancellation while reading body)
大家使用net/http 建立的http server,默认的请求url path是大小写敏感的:
s.mux.HandleFunc("/leader", func(w http.ResponseWriter, r *http.Request) {
}
s.mux.HandleFunc("/LEADER", func(w http.ResponseWriter, r *http.Request) {
}
以上会被认定为不同的路由path。
探究源码:ServeMux使用map[string]muxEntry
哈希表来存储路由。
这与aspnet core的路由行为是不一样的,/hello、/HELLO都会命中下面的路由。
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/hello", async context =>
{
await context.Response.WriteAsync("Hello!");
});
}
URLs in general are case-sensitive (with the exception of machine names). There may be URLs, or parts of URLs, where case doesn't matter, but identifying these may not be easy. Users should always consider that URLs are case-sensitive。
大意是说: 除了domain主机名
是大小写不敏感,url一般被认为是大小写敏感。
The scheme and host are case-insensitive and normally provided in lowercase; all other components are compared in a case-sensitive manner.
在 Go 语言中,客户端请求信息都封装到了Request
对象,但是发送给客户端的响应并不是 Response 对象,而是ResponseWriter
:
func Home(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Welcome to my blog site")
}
ResponseWriter
是处理器用来创建 HTTP 响应的接口,其源码结构如下所示:
type ResponseWriter interface {
// 用于设置/获取所有响应头信息
Header() Header
// 用于写入数据到响应实体
Write([]byte) (int, error)
// 用于设置响应状态码
WriteHeader(statusCode int)
}
WriteHeader
这个方法名有点误导,其实它并不是用来设置响应头的,该方法支持传入一个整型数据用来表示响应状态码,如果不调用该方法的话,默认响应状态码是 200 OK。
在fasthttp中,设置请求谓词:req.Header.SetMethod("POST"), 这种将谓词作为header的行为,我也是服气。
在fasthttp中, fasthttp.Request.SetRequestURI(uri) uri 需要带上 http:// schema
在fasthttp中, 默认的请求MIME是: application/x-www-form-urlencoded
只能设置一次statuscode, 若多次设置statuscode,以前者优先。
例如尝试以如下方式:
http.NotFound(w, r) # 会调用WriteHeader(404);Write()写入body
w.WriteHeader(http.StatusInternalServerError)
会产生一个告警:2023/01/06 19:19:43 http: superfluous response.WriteHeader call from main.ProxyHandler (proxy.go:25)
, 同时产生404状态码。
可以采用如下方式清晰定义状态码和body
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintln(w, "404 page not found")
本周摸鱼快报,阅读时间3min;难度星:3(满星5星);价值度:3(满分5分)。