React对接Go后端出现CORS凭证请求拦截问题求助
问题重现
通过React登录表单向Go后端提交凭证时,触发CORS错误:
"A cross-origin resource sharing (CORS) request was blocked because it was configured to include credentials but the Access-Control-Allow-Credentials response header of the request or the associated preflight request was not set to true."
curl测试后端正常,React端能正确输出输入内容,但跨域请求失败,已尝试设置Access-Control-Allow-Credentials: true但问题未解决。
核心问题排查
从你提供的Go代码来看,存在两个潜在问题:
1. 重复的错误响应写入
在loginHandler中,当请求方法不是POST时,连续调用了两次http.Error:
if r.Method != "POST" { http.Error(w, "Method is not supported", http.StatusMethodNotAllowed) http.Error(w, "test", http.StatusMethodNotAllowed) // 重复调用 return }
http.Error会修改响应头(如Content-Type)并写入响应体,重复调用会导致响应内容混乱,可能干扰浏览器对CORS头的解析。
2. 前端请求的凭证配置缺失(大概率)
即使后端正确设置了Access-Control-Allow-Credentials: true,如果React端的请求未配置携带凭证,浏览器仍会拦截请求。
修复步骤
步骤1:修复后端代码的重复错误响应
修改loginHandler中的错误处理逻辑,保留一次http.Error调用即可:
func loginHandler(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { http.Error(w, "Method is not supported", http.StatusMethodNotAllowed) return // 移除重复的http.Error调用 } var creds Credentials err := json.NewDecoder(r.Body).Decode(&creds) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } w.Header().Set("Content-Type", "application/json") fmt.Printf("login attempt username: %v\n", creds) json.NewEncoder(w).Encode(creds) }
步骤2:确保前端请求配置携带凭证
根据你使用的HTTP库,添加凭证携带配置:
若使用fetch:
fetch('http://localhost:8080/login', { method: 'POST', credentials: 'include', // 关键配置:携带跨域凭证 headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ username: yourUsername, password: yourPassword }), })
若使用axios:
axios.post('http://localhost:8080/login', { username: yourUsername, password: yourPassword }, { withCredentials: true } // 关键配置:携带跨域凭证 )
步骤3:清除浏览器缓存
浏览器可能缓存了旧的CORS响应头,清除缓存后重新测试请求。
验证修复
重启Go后端,重新提交React登录表单:
- 后端应正常接收并打印登录凭证
- 浏览器控制台不再出现CORS拦截错误
内容的提问来源于stack exchange,提问作者Infusca

