[컴][웹] AdoniJS 에서 File Upload

아도니스 / 업로드 / 파일 업로드

AdoniJS 에서 file upload

file 의 upload 와 함께, file 이름도 함께 server 로 전달하고 싶었다. 그래서 처음에 client side 의 FormData 에 field 를 하나 더 추가해서 server 로 보냈다.
...
onClickUpload() {
  ...
  // @ref : https://reactjs.org/docs/uncontrolled-components.html#the-file-input-tag
  const file = this.fileInput.current.files[0];
  if (file) {
    const reqData = new FormData(); // eslint-disable-line
    reqData.append('file', file);
    reqData.append('alias', this.state.alias);

    this.props.uploadFile(this.props.url, reqData);
  }
}

render() {
  return (
    <div className="">
      <input type="text" placeholder="alias 별칭" name="alias" onChange={this.onChangeAlias} />
      <input
        type="file"
        className="form-control"
        name={this.props.name}
        ref={this.fileInput}
      />
      <button
        type='button'
        onClick={this.onClickUpload}
        disabled={this.props.uploadStatus === 'WAITING'}
      >
        UPLOAD
      </button>
      <div>
        {this.state.message}
      </div>
    </div>
  );
}
...

문제점

그래서 서버쪽에서는 아래처럼 처리를 하려고 했다. 하지만 문제는 request.multipart.field 로 등록한 callback 과 request.multipart.file 에서 등록한 callback 중 어느 것이 먼저 동작할 지 알 수 없는 것이다. 순서에 대한 보장이 되지 않는다. [ref. 1]



  async uploadEventBanner({ request, response }) {

    let fileUrl, dstPath;
    try {
      // const alias = inputData.alias;
      const bButler = new BannerButler();
      let body = {};
      request.multipart.field((name, value) => {
        // 이것이 request.multipart.file 의 callback 보다 먼저 실행되지 않는다.        
        body[name] = value;
      });

      // 'file' is name attribute of form-data
      request.multipart.file('file', {}, async (file) => {
        dstPath = bButler.getDstPath(file, alias);
        await bButler.upload(file, dstPath);
      });
      await request.multipart.process();

      fileUrl = bButler.getFileUrl(dstPath);
      await bButler.insertEventBannerInfo(alias, inputData.notice_id, fileUrl);

    } catch (e) {
      console.error(e.stack);
      return response.status(400).json({ error: e.message });
    }

    return response.json({ message: 'upload_completed', url: fileUrl });
  }

대안

ref.1 에서 비슷한 경우가 있어서 답변을 보니 다음 2가지 방법으로 처리가 가능할 듯 했다.
  1. alias 를 query string 으로 넘기는 방법 : 이방법이 지금으로서는 최선인 듯 하다.
  2. GB 정도의 사이즈를 다루는 것이 아니라면, upload 를 직접 처리하는 방법: 이것은 아마도 ref. 2 에서 처럼 직접 file 을 다루는 방법을 이야기하는 듯 하다.

See Also

  1. HTTP Tests

Reference

  1. How to get request values with processManually · Issue #1092 · adonisjs/core · GitHub
  2. File Uploads

댓글 없음:

댓글 쓰기