关于go-zero跨域自定义header的问题
场景说明:
在前后端分离的开发中,前端是单独部署的,可能是一个www.aaa.com的域名,而用go-zero的后端程序,可能部署在了www.bbb.com,这种方式在处理用户登陆的时候,基本上用的是jwt,用到jwt 基本上就要用到自定义header 的问题,比如header 里面可能会传Authorization这样的header头,但是Authorization这个又不是标准的响应头具体可以参考:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
然后看了一下官方的关于跨域的请求方式
package rest import "net/http" const ( allowOrigin = "Access-Control-Allow-Origin" allOrigins = "*" allowMethods = "Access-Control-Allow-Methods" allowHeaders = "Access-Control-Allow-Headers" headers = "Content-Type, Content-Length, Origin" methods = "GET, HEAD, POST, PATCH, PUT, DELETE" ) // CorsHandler handles cross domain OPTIONS requests. // At most one origin can be specified, other origins are ignored if given. func CorsHandler(origins ...string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if len(origins) > 0 { w.Header().Set(allowOrigin, origins[0]) } else { w.Header().Set(allowOrigin, allOrigins) } w.Header().Set(allowMethods, methods) w.Header().Set(allowHeaders, headers) w.WriteHeader(http.StatusNoContent) }) }
这个写得很简单,属于 简单跨域请求,满足不了,
前后端分离的复杂跨域请求(因为是要做自定义header)
然后我自己写他一个小例子
package main import ( "net/http" "fmt" ) func main() { http.HandleFunc("/votes/enroll/lists", TestCrossOrigin) http.ListenAndServe(":8001", nil) } func TestCrossOrigin(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin","http://localhost:8084") w.Header().Add("Access-Control-Allow-Headers","Content-Type,Token") w.Header().Set("Access-Control-Allow-Credentials","true") fmt.Fprintln(w,"hello cros!") }
启动服务
➜ src go run main.go
客户端是用uniapp写的:
uni.request({ header:{ 'authorization':"ok!!!!", 'beid':1, 'ptyid':2, 'authorization':'2323', }, //withCredentials:true, // url: this.$host + 'api/news', url: 'http://localhost:8001/votes/enroll/lists?actid=1&keyword=5', //url: 'http://localhost:8887/votes/enroll/lists?actid=1&keyword=5', //url: 'http://www.aaa.com/votes/enroll/lists?actid=1&keyword=5', data: this.requestParams, success: (result) => { console.log(result); } })
各种试都能成功,显示 不域名
但是换成go-zero的,我改了一下handlers.go的内容
package rest import "net/http" const ( allowOrigin = "Access-Control-Allow-Origin" allOrigins = "*" allowMethods = "Access-Control-Allow-Methods" allowHeaders = "Access-Control-Allow-Headers" headers = "Content-Type, Content-Length, Origin" methods = "GET, HEAD, POST, PATCH, PUT, DELETE" ) // CorsHandler handles cross domain OPTIONS requests. // At most one origin can be specified, other origins are ignored if given. func CorsHandler(origins ...string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin","http://localhost:8084") w.Header().Add("Access-Control-Allow-Headers","Content-Type,Token") w.Header().Set("Access-Control-Allow-Credentials","true")
w.Write([]byte("ok"))
})
}
写成一模一样都不行,于是我抓包分析
go-zero改的抓包
Frame 9483: 824 bytes on wire (6592 bits), 824 bytes captured (6592 bits) on interface lo0, id 0
Null/Loopback
Internet Protocol Version 6, Src: ::1, Dst: ::1
Transmission Control Protocol, Src Port: 59159, Dst Port: 8887, Seq: 1, Ack: 1, Len: 748
Hypertext Transfer Protocol
OPTIONS /votes/enroll/lists?actid=1&keyword=5&columnId=0&minId=0&pageSize=10&column=id%2Cpost_id%2Ctitle%2Cauthor_name%2Ccover%2Cpublished_at%2Ccomments_count&time=1611816221697 HTTP/1.1\r\n
Host: localhost:8887\r\n
Connection: keep-alive\r\n
Pragma: no-cache\r\n
Cache-Control: no-cache\r\n
Accept: */*\r\n
Access-Control-Request-Method: GET\r\n
Access-Control-Request-Headers: authorization,beid,ptyid\r\n
Origin: http://localhost:8085\r\n
User-Agent: Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Mobile Safari/537.36\r\n
Sec-Fetch-Mode: cors\r\n
Sec-Fetch-Site: same-site\r\n
Sec-Fetch-Dest: empty\r\n
Referer: http://localhost:8085/\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
\r\n
[Full request URI: http://localhost:8887/votes/enroll/lists?actid=1&keyword=5&columnId=0&minId=0&pageSize=10&column=id%2Cpost_id%2Ctitle%2Cauthor_name%2Ccover%2Cpublished_at%2Ccomments_count&time=1611816221697]
[HTTP request 1/1]
[Response in frame: 9485]
Frame 5624: 336 bytes on wire (2688 bits), 336 bytes captured (2688 bits) on interface lo0, id 0
Null/Loopback
Internet Protocol Version 6, Src: ::1, Dst: ::1
Transmission Control Protocol, Src Port: 8887, Dst Port: 59159, Seq: 2, Ack: 749, Len: 260
Hypertext Transfer Protocol
HTTP/1.1 200 OK\r\n
Access-Control-Allow-Credentials: true\r\n
Access-Control-Allow-Headers: Content-Type,Token\r\n
Access-Control-Allow-Origin: http://localhost:8084\r\n
Date: Thu, 28 Jan 2021 06:41:42 GMT\r\n
Content-Length: 2\r\n
Content-Type: text/plain; charset=utf-8\r\n
\r\n
[HTTP response 1/1]
[Time since request: 0.007791000 seconds]
[Request in frame: 5606]
[Request URI: http://localhost:8887/votes/enroll/lists?actid=1&keyword=5&columnId=0&minId=0&pageSize=10&column=id%2Cpost_id%2Ctitle%2Cauthor_name%2Ccover%2Cpublished_at%2Ccomments_count&time=1611816102966]
File Data: 2 bytes
Line-based text data: text/plain (1 lines)
自己写的
Frame 7369: 824 bytes on wire (6592 bits), 824 bytes captured (6592 bits) on interface lo0, id 0
Null/Loopback
Internet Protocol Version 6, Src: ::1, Dst: ::1
Transmission Control Protocol, Src Port: 63167, Dst Port: 8001, Seq: 1, Ack: 1, Len: 748
Hypertext Transfer Protocol
OPTIONS /votes/enroll/lists?actid=1&keyword=5&columnId=0&minId=0&pageSize=10&column=id%2Cpost_id%2Ctitle%2Cauthor_name%2Ccover%2Cpublished_at%2Ccomments_count&time=1611816281059 HTTP/1.1\r\n
Host: localhost:8001\r\n
Connection: keep-alive\r\n
Pragma: no-cache\r\n
Cache-Control: no-cache\r\n
Accept: */*\r\n
Access-Control-Request-Method: GET\r\n
Access-Control-Request-Headers: authorization,beid,ptyid\r\n
Origin: http://localhost:8085\r\n
User-Agent: Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Mobile Safari/537.36\r\n
Sec-Fetch-Mode: cors\r\n
Sec-Fetch-Site: same-site\r\n
Sec-Fetch-Dest: empty\r\n
Referer: http://localhost:8085/\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
\r\n
[Full request URI: http://localhost:8001/votes/enroll/lists?actid=1&keyword=5&columnId=0&minId=0&pageSize=10&column=id%2Cpost_id%2Ctitle%2Cauthor_name%2Ccover%2Cpublished_at%2Ccomments_count&time=1611816281059]
[HTTP request 1/2]
[Response in frame: 7371]
[Next request in frame: 7383]
Frame 515: 352 bytes on wire (2816 bits), 352 bytes captured (2816 bits) on interface lo0, id 0
Null/Loopback
Internet Protocol Version 6, Src: ::1, Dst: ::1
Transmission Control Protocol, Src Port: 8001, Dst Port: 58202, Seq: 1, Ack: 749, Len: 276
Hypertext Transfer Protocol
HTTP/1.1 200 OK\r\n
Access-Control-Allow-Credentials: true\r\n
Access-Control-Allow-Headers: Content-Type,Token,authorization,beid,ptyid\r\n
Access-Control-Allow-Origin: *\r\n
Date: Thu, 28 Jan 2021 06:14:17 GMT\r\n
Content-Length: 12\r\n
Content-Type: text/plain; charset=utf-8\r\n
\r\n
[HTTP response 1/2]
[Time since request: 0.000118000 seconds]
[Request in frame: 513]
[Next request in frame: 517]
[Next response in frame: 519]
[Request URI: http://localhost:8001/votes/enroll/lists?actid=1&keyword=5&columnId=0&minId=0&pageSize=10&column=id%2Cpost_id%2Ctitle%2Cauthor_name%2Ccover%2Cpublished_at%2Ccomments_count&time=1611814457976]
File Data: 12 bytes
Line-based text data: text/plain (1 lines)
几乎差不多,真的搞不懂了,后面,实在没有bugs ,直接改的nginx
server { listen 80; server_name www.aaa.com; location / { proxy_connect_timeout 1000; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $http_host; proxy_http_version 1.1; proxy_set_header Connection ""; if ($request_method = 'OPTIONS') { add_header Cache-Control private; add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Max-Age' 86400; add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Token,DNT,Content-Type,Cache-Control,User-Agent,Keep-Alive,Authorization,authorization,beid,ptyid'; return 204; } add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,token'; proxy_pass http://http_ss_soholly; } } upstream http_ss_soholly { server 172.29.4.251:8887; keepalive 256;
算还是把问题解决了