前端服務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 命令來安裝這個中間件。
go get github.com/gin-contrib/cors
package appimport ("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 stringif 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
設置預檢請求的最大緩存時間。