package utils import ( "bytes" "crypto/tls" "encoding/json" "fmt" "io" "net/http" "time" ) // PostJSON 向指定 URL 发起 HTTPS POST 请求,支持自定义请求头和 JSON body。 // 参数: // - url: 完整请求地址(支持 https) // - headers: 自定义请求头(可为 nil) // - body: 将被序列化为 JSON 的数据(可为 map/struct) // - timeout: 请求超时时间 // - insecureSkipVerify: 是否跳过 TLS 证书校验(测试环境可设为 true) // // 返回值: HTTP 状态码、响应体字节、错误 func PostJSON(url string, headers map[string]string, body interface{}, timeout time.Duration, insecureSkipVerify bool) (int, []byte, error) { // 序列化 body var buf bytes.Buffer if body != nil { enc := json.NewEncoder(&buf) if err := enc.Encode(body); err != nil { return 0, nil, fmt.Errorf("encode body to json: %w", err) } } // 自定义 transport 支持跳过证书校验 tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: insecureSkipVerify}, } client := &http.Client{Transport: tr, Timeout: timeout} req, err := http.NewRequest(http.MethodPost, url, &buf) if err != nil { return 0, nil, fmt.Errorf("create request: %w", err) } // 默认 Content-Type 为 application/json req.Header.Set("Content-Type", "application/json") for k, v := range headers { if k == "Content-Type" { req.Header.Set(k, v) continue } req.Header.Set(k, v) } resp, err := client.Do(req) if err != nil { return 0, nil, fmt.Errorf("do request: %w", err) } defer resp.Body.Close() respBytes, err := io.ReadAll(resp.Body) if err != nil { return resp.StatusCode, nil, fmt.Errorf("read response: %w", err) } return resp.StatusCode, respBytes, nil } // PostJSONDefault 简化版,使用 10s 超时且默认验证证书 func PostJSONDefault(url string, headers map[string]string, body interface{}) (int, []byte, error) { return PostJSON(url, headers, body, 10*time.Second, false) }