前端服务8080访问后端8081这端口显示跨域了
ERROR Network Error AxiosError: Network Error at XMLHttpRequest.handleError (webpack-internal:///./node_modules/axios/lib/adapters/xhr.js:116:14) at Axios.request (webpack-internal:///./node_modules/axios/lib/core/Axios.js:58:41) at async getCurrentUser (webpack-internal:///./src/api/user.ts:50:10) at async Proxy.fetchLoginUser (webpack-internal:///./src/store/useLoginUserStore.ts:17:17)
跨域问题通常是由于浏览器的同源策略导致的。需要在 Gin 服务器中启用 CORS(跨域资源共享)。Gin 提供了一个中间件 gin-contrib/cors
来方便地处理 CORS 请求。
启用 CORS 的步骤:
安装gin-contrib/cors
中间件:
可以使用 go get 命令来安装这个中间件。
shell
go get github.com/gin-contrib/cors
go
package app
import (
"fmt"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"log"
"net/http"
"time"
)
func HttpServer() {
ginServer := gin.Default()
// 配置 CORS 中间件
config := cors.DefaultConfig()
config.AllowOrigins = []string{"http://localhost:8080"} // 允许8080来源的请求,生产环境中建议指定具体的域名
config.AllowMethods = []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"} // 允许的请求方法
config.AllowHeaders = []string{"Origin", "Content-Length", "Content-Type", "Authorization"} // 允许的请求头
config.ExposeHeaders = []string{"Content-Length"} // 允许的响应头
config.AllowCredentials = true // 允许携带凭证
config.MaxAge = 12 * time.Hour // 预检请求缓存时间
ginServer.Use(cors.New(config)) // 使用 CORS 中间件
// 注册路由和处理函数
ginServer.POST("/api/backup", backupHandler)
ginServer.POST("/api/user/register", userRegisterHandler)
ginServer.POST("/api/user/login", userLoginHandler)
ginServer.POST("/api/user/logout", userLogoutHandler)
ginServer.GET("/api/user/current", getCurrentUserHandler)
ginServer.GET("/api/user/search", searchUserHandler)
ginServer.POST("/api/user/delete", deleteUserHandler)
if err := ginServer.Run(":8081"); err != nil {
log.Fatalf("HTTP server failed to start: %v", err)
}
}
// 备份处理函数
func backupHandler(context *gin.Context) {
var login struct {
Username string `json:"username"`
Password string `json:"password"`
}
if err := context.ShouldBindJSON(&login); err != nil {
context.JSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "invalid request",
})
return
}
if login.Username == "admin" && login.Password == "123456" {
context.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"msg": "success",
})
fmt.Println("成功执行这个代码")
} else {
context.JSON(http.StatusUnauthorized, gin.H{
"code": http.StatusUnauthorized,
"msg": "invalid credentials",
})
}
}
// 用户注册处理函数
func userRegisterHandler(context *gin.Context) {
var user struct {
Username string `json:"username"`
Password string `json:"password"`
}
if err := context.ShouldBindJSON(&user); err != nil {
context.JSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "invalid request",
})
return
}
// 检查用户名是否已存在
// 这里可以添加数据库操作或其他逻辑
if user.Username == "admin" {
context.JSON(http.StatusConflict, gin.H{
"code": http.StatusConflict,
"msg": "username already exists",
})
return
}
// 添加新用户
// 这里可以添加数据库操作或其他逻辑
fmt.Println("User registered:", user.Username)
context.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"msg": "user registered successfully",
})
}
// 用户登录处理函数
func userLoginHandler(context *gin.Context) {
var user struct {
Username string `json:"username"`
Password string `json:"password"`
}
if err := context.ShouldBindJSON(&user); err != nil {
context.JSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "invalid request",
})
return
}
// 验证用户名和密码
// 这里可以添加数据库操作或其他逻辑
if user.Username == "admin" && user.Password == "123456" {
context.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"msg": "login successful",
})
return
}
context.JSON(http.StatusUnauthorized, gin.H{
"code": http.StatusUnauthorized,
"msg": "invalid credentials",
})
}
// 用户登出处理函数
func userLogoutHandler(context *gin.Context) {
// 这里可以添加登出逻辑,例如清除会话等
context.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"msg": "logout successful",
})
}
// 获取当前用户信息处理函数
func getCurrentUserHandler(context *gin.Context) {
// 这里可以添加获取当前用户逻辑,例如从会话中获取用户信息
user := struct {
Username string `json:"username"`
}{Username: "admin"} // 示例用户
context.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"msg": "success",
"user": user,
})
}
// 获取用户列表处理函数
func searchUserHandler(context *gin.Context) {
username := context.Query("username")
user := struct {
Username string `json:"username"`
}{Username: username} // 示例用户
context.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"msg": "success",
"user": user,
})
}
// 删除用户处理函数
func deleteUserHandler(context *gin.Context) {
var id string
if err := context.ShouldBindJSON(&id); err != nil {
context.JSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "invalid request",
})
return
}
// 删除用户逻辑
// 这里可以添加数据库操作或其他逻辑
fmt.Println("User deleted:", id)
context.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"msg": "user deleted successfully",
})
}
说明
- 安装
gin-contrib/cors
:使用go get github.com/gin-contrib/cors
安装中间件。 - 配置 CORS 中间件:在
HttpServer
函数中使用cors.DefaultConfig()
配置 CORS 设置,并将其应用到 Gin 服务器。 - 允许的来源:
config.AllowOrigins = []string{"*"}
允许所有来源的请求。在生产环境中,建议指定具体的域名以提高安全性。 - 允许的方法:
config.AllowMethods
指定允许的 HTTP 方法。 - 允许的头部:
config.AllowHeaders
指定允许的请求头部。 - 暴露的头部:
config.ExposeHeaders
指定允许暴露的响应头部。 - 允许凭证:
config.AllowCredentials
允许发送凭证(如 cookies)。 - 最大缓存时间:
config.MaxAge
设置预检请求的最大缓存时间。