はじめに
multipart/form-data
を使って画像を投げる処理を実装する機会があったのでそれについてメモがてら
どうせすぐ忘れちゃうしね!
ついでに誰かの役に立てば
実装
なんとなくDIO
を使ってみたかったのでhttp
ではなく今回はDIO
を使ってます(ちゃんと選定して使え)
基本的にDIO
のREADME.mdに書いてある実装通りする感じで問題ないです
下のURLのUploading multiple files to server by FormData
のSampleを参考にしてください
https://pub.dev/packages/dio#examples
とりあえずやってみた実装はこんな感じ
色々省いてるので実装する際は細かいところもちゃんと書いたほうがいいです。
FormData
を使うとContent-Type
をmultipart/form-data
として扱ってくれるらしい
Future<Object?> uploadFile({
required String url,
required File file,
}) async {
final dio = Dio();
final formData = FormData.fromMap({
'file': await MultipartFile.fromFile(
file.path,
filename: file.path.split('/').last,
),
});
final response = await dio.post(
url,
formData
);
return response.data;
}
動かしてみよう
サーバーサイドの方の設定によってはこれでいけるかもしれません
ただ自分の場合は415が返ってきました
なにそれ
調べてみるとこういうエラーらしい
415 Unsupported Media Type
HTTP 415 Unsupported Media Type クライアントエラーレスポンスコードは、ペイロードフォーマットがサポートされていないフォーマットであるため、サーバーがリクエストの受け入れを拒否することを示します。
フォーマットの問題はリクエストされた Content-Type または Content-Encoding によるものか、または直接データを検査した結果に起因する可能性があります。
ほー
んじゃContent-Type
を設定すればいいのか〜
どうやらサーバー側ではContent-Type
がimage/jpeg
以外は弾いているらしいので415が返ってきてたみたいです
ちなみにMultipartFile
側でこっちからContent-Type
を指定しなかった場合は以下のように設定されてるようでした
application/octet-stream
こいつはこういうやつらしい
汎用的なバイナリデータ (または本当のタイプが不明なバイナリデータ) は application/octet-stream です。
はじめてしった
MultipartFileにContent-Typeを指定する
MultipartFile
の引数のcontentType
の型はMediaType
なので、
まずは以下のパッケージをimportします
import 'package:http_parser/http_parser.dart';
そこからcontentType
に以下のようにMediaType
を渡しましょう
'file': await MultipartFile.fromFile(
file.path,
filename: file.path.split('/').last,
// ここ↓
contentType: MediaType.parse('image/jpeg'),
),
動かしてみると
200が返ってきた
俺の勝ち!
最後に
いつになったらプログラミング初心者を卒業できるんだろうか
間違ってたら優しい口調で教えてください
そして相変わらず日本語は難しい