新規投稿
フォローする

バイナリファイルのアップロード

MSのACCESS(VBA)からKINTONEのデータを取得、更新、登録、削除を
おこなおうと試みています。

添付ファイルのアップロードで、
HTTPリクエストをテストしています。

API説明ページのサンプルを参考に、
テキストファイルのアップロード(一時アップ)は
できた(filekeyのレスポンスがかえってきた)のですが、
バイナリデータ(jpg画像など)をアップロードするにはどのようにすればよいのか
詰まってしまっています。

ADODB.Streamでjpgファイルをロードして
Content-Typeをapplication/octet-streamに、
Content-Transfer-Encoding: binaryとして
リクエストしましたが「不正なリクエストです」とエラーになってしまいます。

よいサンプルコードなど教示いただけないでしょうか?

0

4件のコメント

Avatar
斎藤 栄

やまこうさん
kintone側の話ではなくVBA側の話になってしまうのでサンプルコードはありませんが、kintoneのAPI説明ページには以下のように記載されています。

・リクエストは multipart/form-data 形式で送信します。
 詳細は RFC1867、RFC2388 を参照してください。

https://developers.cybozu.com/ja/kintone-api/apprec-fileuploadapi.html

kintone側の仕様は上記だとして、クライアント側の実装についてはADODB.Streamを使った一般的な画像アップロードのサンプルなどをネットで検索してみてはいかがでしょうか?

0
Avatar
山下 竜

こんばんは。

こちらを参考に書いてみました。Excel2013動作確認済みですが、多分Accessでも大丈夫ではないかと思います。
http://trash-area.com/archives/649

''''''''' start of VBA

Sub fileUpload()
' ファイルの情報設定
localfileName = "c:\photo3.jpg" 'アップロード元のファイル
FileName = "image.jpeg" 'アップロード後のファイル名
mimeType = "image/jpeg" 'ファイルのmime-type
' kintoneアクセス情報の設定
subdomain = "[your subdomain]" 'サブドメイン
authToken = "[your base64-encoded string]" '「ユーザID : パスワード」のbase64エンコードストリング

Const adTypeBinary = 1
Const adTypeText = 2
Boundary = "---------------------------9223d5ca69cc69903961a3c3126146c2"
END_BOUNDARY = vbCrLf + "--" + Boundary + "--" + vbCrLf

Dim fileContents
Dim stream: Set stream = CreateObject("ADODB.Stream")
stream.Type = adTypeBinary
stream.Open
stream.LoadFromFile localfileName
fileContents = stream.Read
stream.Close

Dim params: params = ""
params = params + "--" + Boundary + vbCrLf
params = params + "Content-Disposition: form-data; name=""" + "file" + """;"
params = params + " filename=""" + FileName + """" + vbCrLf
params = params + "Content-Type:" + mimeType + vbCrLf + vbCrLf

stream.Type = adTypeText
stream.Charset = "UTF-8"
stream.Open

' バイナリデータの前まで
ChangeStreamType stream, adTypeText
stream.WriteText params

' バイナリデータ
ChangeStreamType stream, adTypeBinary
stream.Write fileContents

' 最後
ChangeStreamType stream, adTypeText
stream.WriteText END_BOUNDARY

ChangeStreamType stream, adTypeBinary
stream.Position = 0
formData = stream.Read
stream.Close

' HTTPSリクエスト
Set http = CreateObject("WinHttp.WinHttpRequest.5.1")

http.Open "POST", "https://" + subdomain + ".cybozu.com/k/v1/file.json", False
http.SetRequestHeader "X-Cybozu-Authorization", authToken

http.SetRequestHeader "Content-Type", "multipart/form-data; boundary=" & Boundary

http.Send formData

' fileKeyの取得
MsgBox http.ResponseText
Debug.Print http.ResponseText
Range("A1").Value = http.ResponseText

End Sub

Function ChangeStreamType(stream, t)
p = stream.Position
stream.Position = 0
stream.Type = t
stream.Position = p
Set ChangeStreamType = stream
End Function

''''''''' end of VBA

参考になれば幸いです。

1
Avatar
やーさん

kintoneの話にならないですね、すみません。
サンプルをネットで検索していろいろ試してみましたが、
うまくいかず、投稿いたしました。
勉強します。

山下さん

実際のコードまでアップしていただき、感謝します。
accessでもコードそのままで使用できました。
おかげさまで実現したかったことは、なんとかなりそうです。
ただ、自分で書いたコードの何がダメなのかが、いまいちわからないままで、
不完全燃焼なので、それは調べてみます。

ちなみに、下記のようなコードで、
「{"message":"不正なリクエストです。","id":"00000000000-00000000000","code":"CB_IL02"}」
と返ってきました。

おそらくバイナリとテキストを単純にくっつけてはダメということでしょうね。
勉強になりました。

Dim objweb As Object
Dim str As String
Dim s As String

Const adTypeBinary = 1
Const adTypeText = 2

Set objweb = CreateObject("MSXML2.ServerXMLHTTP.6.0")

Dim FilePath As String

' FilePath = "C:\1.txt"
FilePath = "C:\1.jpg"

Set stream = CreateObject("ADODB.Stream")
stream.Open
stream.Position = 0
stream.TYPE = adTypeBinary
stream.LoadFromFile FilePath

'オブジェクトの生成に失敗していれば処理終了
If objweb Is Nothing Then
Exit Sub
End If

objweb.Open "POST", TARGET_URL & url, False
objweb.SetRequestHeader "HOST:", "xxxxxx.cybozu.com:443"
objweb.SetRequestHeader "X-Cybozu-Authorization", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
objweb.SetRequestHeader "Content-Type", "multipart/form-data; boundary = ""AaB03x"""

str = ""
str = str & "--AaB03x" & vbCrLf
str = str & "Content-Disposition: form-data; name =""file""; filename=""1.jpg""" & vbCrLf
str = str & "Content-Type: image/jpg" & vbCrLf

str = str & stream.Read & vbCrLf

str = str & "--AaB03x--"

'// HttpRequestを送信する
objweb.send (str)

'// レスポンスの確認
s = objweb.ResponseText
MsgBox s

Set objweb = Nothing

0
Avatar
山下 竜

 やまこうさん

 私もVBAやmultipart伝送はあまり理解出来ていないのですが、仰っている通り、ファイルの中身を記載する部分はバイナリorテキスト、挟み込むboundaryは前後テキストとして形成する必要があるようです。
 cURL等ライブラリに任せていると、この辺の理解が出来てなくてもあっさりアップロード/ダウンロード出来てしまうので、私も勉強したいと思います(^^;
 また、kintoneは使っていく中でこういった所で開発者に理解を促し、成長させてくれる点でも良いサービスだなぁとつくづく思います!

0
サインインしてコメントを残してください。