はじめに
Alibaba の Ant Design が結構イケてます。
特に Upload Component がおしゃれな挙動をしてくれるんですが、デフォルトで POST で送信しちゃうようです。
PUT で送信する要件があったのでそのナレッジを書いておきます。
PUT を使った Upload
いきなり本題です。
Class / Stateless Functional Component は省略します。
実装箇所がわかりやすいようにrender
以降の部分を記載します。
(Stateless Functional Component の場合はreturn
以降をご参考ください。)
import { Upload, Icon } from 'antd';
/*** 中略 ***/
createButton = () => {
return (
<div>
<Icon type={'plus'} />
<div className="ant-upload-text">Upload</div>
</div>
);
}
render() {
return (
<Upload
name={fileName}
listType="picture-card"
className="avatar-uploader"
multiple={false}
showUploadList={{ showPreviewIcon: false, showRemoveIcon: true }}
fileList={fileList}
action={uploadUrl}
customRequest={(info) => {
let xhr = new XMLHttpRequest();
if (!uploadUrl) { return; }
if (info.onProgress && xhr.upload) {
xhr.upload.onprogress = function progress(e) {
if (e.total > 0) {
e.percent = e.loaded / e.total * 100;
}
info.onProgress(e);
}
}
xhr.open('PUT', uploadUrl, true);
xhr.overrideMimeType(info.file.type)
xhr.send(info.file);
xhr.addEventListener('loadend', (e) => {
info.onSuccess(e, xhr);
})
}}
onPreview={(file) => {
console.log('onPreview',file);
}}
onRemove={(file) => {
console.log('onRemove',file);
}}
beforeUpload={(file) => {
console.log('beforeUpload',file);
}}
onChange={(info) => {
console.log('onChange',info);
}
>
{fileList.length >= 1 ? null : this.createButton()}
</Upload>
);
}
処理の説明
createButton
アップロード前に表示するボタンアイコンのコンポーネントを作成しています。
multiple
一つのコンポーネントに対して、複数ファイルをアップロードできるかどうかの設定。
defaultでfalse
なので書かなくても同じ挙動になります。
showUploadList
アップロード後のサムネイルにカーソルを当てた際、プレビューアイコンとリムーブアイコンを表示する設定です。
fileList
アップロードしたファイルの情報。
初期表示したいときは、この項目に値を設定します。
action
アップロード先の URL です。
必須項目ですが、customRequest
で URL 設定した場合は使われないかもしれません。(※未確認)
customRequest
PUT を利用する際、この API を使用します。
私はXMLHttpRequest()
を使いました。
xhr.upload.onprogress = function progress(e) {
if (e.total > 0) {
e.percent = e.loaded / e.total * 100;
}
info.onProgress(e);
}
この処理でプログレスバーを更新します。
xhr.addEventListener('loadend', (e) => {
info.onSuccess(e, xhr);
})
この処理で、処理の完了をコンポーネントに連携します。
PUT の処理は比較的簡単に実装できたのですが、customRequest を利用した場合にUpload
のプログレスバーの UI が動かず色々と試して上記の実装に至りました。
おわりに
もっといい実装方法や、間違いなどがありましたらご指摘いただけますと幸いです。