title: Go の組み込みの net ライブラリと GoFrame を使用してフォームのファイルアップロードとカスタム Cookie を実装する
date: 2021-09-17 13:26:00
toc: true
category:
- Golang
tags: - Golang
- net
- http
- ライブラリ
- GoFrame
- 実装
- フォーム
- ファイル
- アップロード
- カスタム
- Cookie
この記事では、Go 言語を使用して Chainlink の画像アップロードを実装します。
以下の図は、2 つの方法で同じ画像を Chainlink にアップロードする内容を示しています。
以下はコードです:
package main
import (
"bytes"
"context"
"crypto/md5"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
"mime/multipart"
"net/http"
"os"
"path/filepath"
"strings"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/os/glog"
)
const (
// loginUrl ログインURL
loginUrl = "https://ld246.com/login"
// uploadImgUrl 画像アップロードURL
uploadImgUrl = "https://ld246.com/upload/editor"
// uploadImgUrl = "http://localhost:9999"
// uploadFilePath アップロードファイルのパス
uploadFilePath = "C:/Users/biuaxia/Downloads/Snipaste_2021-09-07_15-03-20.png"
)
type loginReqData struct {
NameOrEmail string `json:"nameOrEmail"`
UserPassword string `json:"userPassword"`
Captcha string `json:"captcha"`
}
type loginRespData struct {
Msg string `json:"msg"`
Code int `json:"code"`
Goto string `json:"goto"`
TokenName string `json:"tokenName"`
Token string `json:"token"`
}
// main [Chainlink](http://ld246.com)の画像アップロードインターフェース
func main() {
data := getLoginRespData()
uploadImg(data)
uploadPic(data)
}
// uploadImg goFrameを使用してファイルをアップロードする
func uploadImg(data loginRespData) {
m := make(map[string]string)
m[data.TokenName] = data.Token
r, e := g.Client().
Cookie(m).
Post(uploadImgUrl, "file[]=@file:"+uploadFilePath)
if e != nil {
glog.Error(e)
} else {
fmt.Println("uploadImg-resp:", string(r.ReadAll()))
err := r.Close()
if err != nil {
panic(err)
}
}
}
// uploadPic 原生の方法でファイルをアップロードする
// key:fileにファイルを配置する
// multipart/form-dataでファイルを送信する
func uploadPic(data loginRespData) {
m := make(map[string]string)
m[data.TokenName] = data.Token
var (
buffer = bytes.NewBuffer(nil)
writer = multipart.NewWriter(buffer)
)
formFile, _ := writer.CreateFormFile("file[]", filepath.Base(uploadFilePath))
file, _ := os.Open(uploadFilePath)
_, _ = io.Copy(formFile, file)
defer func(file *os.File) {
err := file.Close()
if err != nil {
panic(err)
}
}(file)
defer func(writer *multipart.Writer) {
err := writer.Close()
if err != nil {
panic(err)
}
}(writer)
req, _ := http.NewRequest("POST", uploadImgUrl, buffer)
req.Header.Set("Content-Type", writer.FormDataContentType())
req = req.WithContext(context.Background())
req.Header.Set("Cookie", data.TokenName+"="+data.Token)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36 Edg/93.0.961.47")
resp, _ := http.DefaultClient.Do(req)
readAll, _ := ioutil.ReadAll(resp.Body)
fmt.Println("uploadPic-resp:", string(readAll))
}
// getLoginRespData ログイン情報を取得します。主にレスポンスから取得したトークンを使用して、チェーンリンクのリクエストのCookie情報を組み立てます。
func getLoginRespData() loginRespData {
ld := loginReqData{
NameOrEmail: "your_account",
UserPassword: getPassword("your_account"),
Captcha: "",
}
// リクエスト内容を準備する
reqBody, _ := json.Marshal(ld)
log.Println("リクエスト内容:", string(reqBody))
resp, _ := http.Post(loginUrl, "application/json", strings.NewReader(string(reqBody)))
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
panic(err)
}
}(resp.Body)
body, _ := ioutil.ReadAll(resp.Body)
log.Println("レスポンス内容:", string(body))
var lrd loginRespData
_ = json.Unmarshal(body, &lrd)
return lrd
}
// getPassword パスワードのMD5ハッシュを取得します。
func getPassword(password string) string {
h := md5.New()
h.Write([]byte(password))
return hex.EncodeToString(h.Sum(nil))
}