package lxCommon import ( "bytes" "crypto/tls" "github.com/bytedance/sonic" "golang.org/x/net/publicsuffix" "io" "io/ioutil" "mime/multipart" "net/http" "net/http/cookiejar" "os" "path/filepath" "time" ) // url 路径 filename 文件的上传参数 func PostFile(url string, files map[string]string, ext map[string]string) ([]byte, error) { res := []byte{} //创建一个模拟的form中的一个选项,这个form项现在是空的 bodyBuf := &bytes.Buffer{} bodyWriter := multipart.NewWriter(bodyBuf) for k, v := range files { //打开文件句柄操作 file, err := os.Open(v) if err != nil { //fmt.Println("error opening file") return res, err } defer file.Close() //相当于现在还没选择文件, form项里选择文件的选项 fileWriter, err := bodyWriter.CreateFormFile(k, filepath.Base(v)) if err != nil { //fmt.Println("error writing to buffer") return res, err } //iocopy 这里相当于选择了文件,将文件放到form中 _, err = io.Copy(fileWriter, file) if err != nil { return res, err } } //获取上传文件的类型,multipart/form-data; boundary=... contentType := bodyWriter.FormDataContentType() //上传的其他参数 for key, val := range ext { _ = bodyWriter.WriteField(key, val) } //这个很关键,必须这样写关闭,不能使用defer关闭,不然会导致错误 bodyWriter.Close() //发送post请求到服务端 resp, err := http.Post(url, contentType, bodyBuf) if err != nil { return res, err } defer resp.Body.Close() res, err = ioutil.ReadAll(resp.Body) if err != nil { return res, err } return res, err } func NewClient() *http.Client { tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } var c = &http.Client{ Timeout: time.Duration(1000 * time.Second), Transport: tr, } options := cookiejar.Options{ PublicSuffixList: publicsuffix.List, } curCookieJar, _ := cookiejar.New(&options) c.Jar = curCookieJar return c } func HttpJsonStr(c *http.Client, method, url string, header map[string]string, body io.Reader, v *string) error { req, err := http.NewRequest(method, url, body) if err != nil { return err } for k, v := range header { req.Header.Add(k, v) } resp, err := c.Do(req) if err != nil { return err } defer resp.Body.Close() by, err := ioutil.ReadAll(resp.Body) *v = string(by) return nil } func HttpJson(c *http.Client, method, url string, header map[string]string, body io.Reader, data interface{}) error { req, err := http.NewRequest(method, url, body) if err != nil { return err } for k, v := range header { req.Header.Add(k, v) } resp, err := c.Do(req) if err != nil { return err } defer resp.Body.Close() by, err := ioutil.ReadAll(resp.Body) if err != nil { return err } err = sonic.Unmarshal(by, data) return err } func HttpGetFile(url, path string) error { res, err := http.Get(url) if err != nil { return err } f, err := os.Create(path) defer f.Close() if err != nil { return err } _, err = io.Copy(f, res.Body) return err } // 流式上传文件 func PostFilePipe(url string, files map[string]string) { r, w := io.Pipe() m := multipart.NewWriter(w) go func() { defer w.Close() defer m.Close() for k, f := range files { part, err := m.CreateFormFile(k, f) if err != nil { continue } file, err := os.Open(f) if err != nil { continue } defer file.Close() if _, err = io.Copy(part, file); err != nil { continue } } }() http.Post(url, m.FormDataContentType(), r) }