CORS 跨域问题笔记

问题描述

前端(localhost:3000)调用后端(localhost:8080)接口时,浏览器控制台报错:

1
2
3
4
Access to XMLHttpRequest at 'http://localhost:8080/users/signup' from origin
'http://localhost:3000' has been blocked by CORS policy: Response to preflight
request doesn't pass access control check: No 'Access-Control-Allow-Origin'
header is present on the requested resource.

Axios 返回 Network Error,请求被浏览器拦截。

原因

浏览器同源策略:端口不同即为跨域。POST 请求会先发 OPTIONS 预检,后端未返回 CORS 头导致拦截。

注:Postman 不受此限制,因为它不是浏览器。

解决方法

1. 安装依赖

1
go get github.com/gin-contrib/cors

2. 添加 CORS 中间件(main.go)

1
2
3
4
5
6
7
8
9
10
11
12
import (
"time"
"github.com/gin-contrib/cors"
)

server.Use(cors.New(cors.Config{
AllowOrigins: []string{"http://localhost:3000"},
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowHeaders: []string{"Origin", "Content-Type", "Authorization"},
AllowCredentials: true,
MaxAge: 12 * time.Hour,
}))

中间件通过 server.Use 挂载,对所有路由生效。

关键配置说明

配置项 作用
AllowOrigins 白名单,指定允许的域名
AllowMethods 允许的 HTTP 方法,OPTIONS 必须包含
AllowHeaders 前端可携带的请求头,如 JWT 的 Authorization
AllowCredentials 是否允许携带 Cookie(为 true 时 AllowOrigins 不能是 *)
MaxAge 预检结果缓存时间,减少重复 OPTIONS

注意

  • 前后端分离项目 CORS 中间件是标配
  • 生产环境 AllowOrigins 必须精确指定,不能写 *
  • 前端端口变更时需同步更新 AllowOrigins