我们都知道啊,跨域问题,是可以在nginx中进行配置的,但是呢,我们的程序中也是可以进行设置,而且前后端也都是可以进行设置,记得我之前发过的一篇文章,大体解释了一下跨域的问题,可以翻翻看看,今天我们将在kit 中,进行跨域的设置
因为kit 不是框架,所以kit没有所谓的针对跨域设置的封装,我们先看几个框架的跨域设置
我们熟悉的go 的框架:gin。iris
先看gin:
package main
import (
"github.com/gin-gonic/gin"
"strings"
"fmt"
"net/http"
)
func main() {
/* 路由初始化*/
engine = gin.Default()
// 允许使用跨域请求 全局中间件
engine.Use(Cors())
// 启动路由 设定端口
engine.Run(":11000")
}
// 跨域设置
func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method //请求方法
origin := c.Request.Header.Get("Origin") //请求头部
var headerKeys []string // 声明请求头keys
for k, _ := range c.Request.Header {
headerKeys = append(headerKeys, k)
}
headerStr := strings.Join(headerKeys, ", ")
if headerStr != "" {
headerStr = fmt.Sprintf("access-control-allow-origin, access-control-allow-headers, %s", headerStr)
} else {
headerStr = "access-control-allow-origin, access-control-allow-headers"
}
if origin != "" {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Origin", "*") // 这是允许访问所有域
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE") //服务器支持的所有跨域请求的方法,为了避免浏览次请求的多次'预检'请求
// header的类型
c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma")
// 允许跨域设置 可以返回其他子段
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar") // 跨域关键设置 让浏览器可以解析
c.Header("Access-Control-Max-Age", "172800") // 缓存请求信息 单位为秒
c.Header("Access-Control-Allow-Credentials", "false") // 跨域请求是否需要带cookie信息 默认设置为true
c.Set("content-type", "application/json") // 设置返回格式是json
}
//放行所有OPTIONS方法
if method == "OPTIONS" {
c.JSON(http.StatusOK, "Options Request!")
}
// 处理请求
c.Next() // 处理请求
}
}
这个是比较详细的设置,我们来看一个简单的跨域设置
iris:func main(){
app := iris.New()
app.UseRouter(CRS)
}
func CRS(ctx iris.Context) {
ctx.Header("Access-Control-Allow-Origin", "*")
ctx.Header("Access-Control-Allow-Credentials", "true")
if ctx.Method() == iris.MethodOptions {
ctx.Header("Access-Control-Methods", "POST, PUT, PATCH, DELETE")
ctx.Header("Access-Control-Allow-Headers", "Access-Control-Allow-Origin,Content-Type,X-API-CHANNEL,Token")
ctx.Header("Access-Control-Max-Age", "86400")
ctx.StatusCode(iris.StatusNoContent)
return
}
ctx.Next()
}
这是简单的设置,gin也可以像iris,一样的去设置,如果你的业务场景需要详细的设置以及 *** 作,那你可以像gin的例子一样去设置iris
----这两个在此只是简单的提一下,重点是我们要去设置我们kit中的跨域问题,但是此前,我们可以提前看一下,框架的封装,是如何实现的跨域设置,或者说 跨域设置的是那个参数
// 用iris为例
// +------------------------------------------------------------+
// | Response Headers helpers |
// +------------------------------------------------------------+
// Header adds a header to the response, if value is empty
// it removes the header by its name.
func (ctx *Context) Header(name string, value string) {
if value == "" {
ctx.writer.Header().Del(name)
return
}
ctx.writer.Header().Add(name, value)
}
我们追进去,看到的是这个,问题:这是那个参数的?
继续追击:关键是ctx.writer 这个写入!!!
// Context is the midle-man server's "object" dealing with incoming requests.
//
// A New context is being acquired from a sync.Pool on each connection.
// The Context is the most important thing on the iris's http flow.
//
// Developers send responses to the client's request through a Context.
// Developers get request information from the client's request a Context.
type Context struct {
// the http.ResponseWriter wrapped by custom writer.
writer ResponseWriter
// the original http.Request
request *http.Request
// the current route registered to this request path.
currentRoute RouteReadOnly
// the local key-value storage
params RequestParams // url named parameters.
values memstore.Store // generic storage, middleware communication.
query url.Values // GET url query temp cache, useful on many URLParamXXX calls.
// the underline application app.
app Application
// the route's handlers
handlers Handlers
// the current position of the handler's chain
currentHandlerIndex int
// proceeded reports whether `Proceed` method
// called before a `Next`. It is a flash field and it is set
// to true on `Next` call when its called on the last handler in the chain.
// Reports whether a `Next` is called,
// even if the handler index remains the same (last handler).
proceeded uint32
}
找到了:写入: writer ResponseWriter 是这个参数!!!
差不多了,追查到这个参数,我们就可以了
那在我们的kit中,这个参数在哪呢?
我们找找
首先是可以定位到路由,router
OK,如图,我们可以一个一个去看,其实,我们思考一个,ResponseWriter,这个写入,我们直接去4 里面查看。
是的了,这个 ResponseWriter 在这,当初我门只是简单的定义了一下,返回值的类型,json格式嘛,既然如此,那我们就在此进行跨域的设置
大家也可以去看看别的,1,2,3,看看能不能找到这个 ResponseWriter,我找了一圈,没有找到,所以我就在这进行的跨域的设置
我们就直接进行简单设置
func EncodeVcResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
SetResponseWrite(&w)
return json.NewEncoder(w).Encode(response)
}
// 设置跨域以及返回值格式
func SetResponseWrite(w *http.ResponseWriter) {
(*w).Header().Set("Access-Control-Allow-Origin", "*")
(*w).Header().Set("Access-Control-Allow-Credentials", "true")
(*w).Header().Set("Access-Control-Methods", "POST, PUT, PATCH, DELETE")
(*w).Header().Set("Access-Control-Allow-Headers", "Access-Control-Allow-Origin,Content-Type,X-API-CHANNEL,Token")
(*w).Header().Set("Access-Control-Max-Age", "86400")
(*w).Header().Set("Content-type", "application/json")
}
这样的话就可以直接使用并解决跨域了
OK 代码提交
https://gitee.com/weishunuan_163com/go.git
– 补充一点,跨域问题的设置,我后期还会修改位置,这次是初步提交
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)