二丫讲梵 二丫讲梵
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)

二丫讲梵

行者常至,为者常成
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)
  • Shell编程

  • Go编程笔记

  • 前端编程笔记

  • Go学习笔记

    • 基础部分

    • web框架

      • 标准库template学习入门
      • gin框架学习入门
      • 解决前端调用后端跨域问题
      • 通过jwt基于token实现登陆认证
    • orm框架

  • Vue-21年学习笔记

  • Vue-22年重学笔记

  • 编程世界
  • Go学习笔记
  • web框架
二丫讲梵
2021-07-10

解决前端调用后端跨域问题

文章发布较早,内容可能过时,阅读注意甄别。

在学习前端的内容,目前在页面上展示一个图表,这些图表的数据其实就是一个 json 数组,内容如下:

[
  { "id": 1, "name": "zhangs", "nickname": "zhangs", "desc": "人之初" },
  { "id": 2, "name": "lis", "nickname": "lis", "desc": "性本善" },
  { "id": 3, "name": "wangw", "nickname": "wangw", "desc": "性相近" },
  { "id": 4, "name": "zhaol", "nickname": "zhaol", "desc": "习相远" },
  { "id": 5, "name": "liuq", "nickname": "liuq", "desc": "苟不教" },
  { "id": 6, "name": "mingb", "nickname": "mingb", "desc": "性乃迁" }
]
1
2
3
4
5
6
7
8

原本这些数据在教学网站上,但是自己想着练手一下,通过 gin 框架来吧这个数组返回,代码如下:

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

type Date struct {
	ID int `json:"id"`
	Name string `json:"name"`
	Nickname string `json:"nickname"`
	Desc string `json:"desc"`
}

func main() {
	r:=gin.Default()
	a:=[]Date{
		{ID:       1, Name:     "zhangs", Nickname: "zhangs", Desc:     "人之初",},
		{ID:       2, Name:     "lis", Nickname: "lis", Desc:     "性本善",},
		{ID:       3, Name:     "wangw", Nickname: "wangw", Desc:     "性相近",},
		{ID:       4, Name:     "zhaol", Nickname: "zhaol", Desc:     "习相远",},
		{ID:       5, Name:     "liuq", Nickname: "liuq", Desc:     "苟不教",},
		{ID:       6, Name:     "mingb", Nickname: "mingb", Desc:     "性乃迁",},
	}
	r.GET("/sys/jslist", func(c *gin.Context) {
		c.IndentedJSON(http.StatusOK, a)
	})

	r.Run(":8000")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

启动 golang 项目之后,赶忙去前端进行一下请求,结果一片空白,什么数据也没有,打开检查发现跨域了,报错如下:

Access to XMLHttpRequest at 'http://127.0.0.1:8000/sys/jslist?pageIndex=1&pageSize=10' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource
1

于是就想着从 go 的层面解决一下,最后在网上找到了答案,调整 go 代码如下:

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"strings"
)

type Date struct {
	ID int `json:"id"`
	Name string `json:"name"`
	Nickname string `json:"nickname"`
	Desc string `json:"desc"`
}

func main() {
	r:=gin.Default()
	r.Use(Cors())
	a:=[]Date{
		{ID:       1, Name:     "zhangs", Nickname: "zhangs", Desc:     "人之初",},
		{ID:       2, Name:     "lis", Nickname: "lis", Desc:     "性本善",},
		{ID:       3, Name:     "wangw", Nickname: "wangw", Desc:     "性相近",},
		{ID:       4, Name:     "zhaol", Nickname: "zhaol", Desc:     "习相远",},
		{ID:       5, Name:     "liuq", Nickname: "liuq", Desc:     "苟不教",},
		{ID:       6, Name:     "mingb", Nickname: "mingb", Desc:     "性乃迁",},
	}

	r.GET("/sys/jslist", func(c *gin.Context) {
		//c.AbortWithStatus(http.StatusNoContent)
		c.IndentedJSON(http.StatusOK, a)

	r.Run(":8000")
}


// 跨域
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()        //  处理请求
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

接着再来请求,发现可以拿到数据了:

image-20200321230030458

参考:https://www.jianshu.com/p/2946513b81fa

微信 支付宝
#go
上次更新: 2024/07/04, 22:40:37
gin框架学习入门
通过jwt基于token实现登陆认证

← gin框架学习入门 通过jwt基于token实现登陆认证→

最近更新
01
记录二五年五一之短暂回归家庭
05-09
02
学习周刊-总第210期-2025年第19周
05-09
03
学习周刊-总第209期-2025年第18周
05-03
更多文章>
Theme by Vdoing | Copyright © 2017-2025 | 点击查看十年之约 | 浙ICP备18057030号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式