关于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"))
       w.WriteHeader(http.StatusOK)

    })
}

写成一模一样都不行,于是我抓包分析

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
Host: localhost:8887
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Accept: */*
Access-Control-Request-Method: GET
Access-Control-Request-Headers: authorization,beid,ptyid
Origin: http://localhost:8085
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
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Sec-Fetch-Dest: empty
Referer: http://localhost:8085/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9

[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
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type,Token
Access-Control-Allow-Origin: http://localhost:8084
Date: Thu, 28 Jan 2021 06:41:42 GMT
Content-Length: 2
Content-Type: text/plain; charset=utf-8

[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
Host: localhost:8001
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Accept: */*
Access-Control-Request-Method: GET
Access-Control-Request-Headers: authorization,beid,ptyid
Origin: http://localhost:8085
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
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Sec-Fetch-Dest: empty
Referer: http://localhost:8085/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9

[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
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type,Token,authorization,beid,ptyid
Access-Control-Allow-Origin: *
Date: Thu, 28 Jan 2021 06:14:17 GMT
Content-Length: 12
Content-Type: text/plain; charset=utf-8

[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;

算还是把问题解决了

原文地址:https://www.cnblogs.com/jackluo/p/14339769.html