ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 8일 차 - 이미지 업로드 일부 구현(Toast UI로 통신 결과 받는 것 까지!)
    project/main 2023. 3. 14. 23:15

    1.  텍스트 에디터

    프로젝트에 텍스트 에디터를 사용하기로 했다. 텍스트 에디터는 글을 작성하는 기능을 구현할 때 단순 textarea를 사용하는 것이 아닌 

    • ckEditor
    • React-MD-Editor
    • Toast UI
    • React-qill

     

    위보다 많은 텍스트 에디터가 존재하지만 이번에 이미지 업로드를 구현하면서 사용해본 에디터들이다. 처음에 React-Md-Editer를 하고 싶기도 했고 가장 이뻐 보이기도 했어서 선택을 했다. 마지막엔 결국 Toast UI로 했다.

     


    2. 이미지 업로드 구조

    이미지 업로드 구조

     

    이미지의 업로드 구조는 위와 같다.

     

    1. Browser에서 image 업로드시 image를 formdata형식으로 Server로 post 요청한다.

    2. image를 받은 Server는 AWS S3 버킷으로 image를 저장한다.

    3. Server에서 AWS S3에 저장된 image의 url을 가져온다.

    4. Server가 가져온 image url을 Browser로 응답해준다.


    3. 구현 과정

    3.1 React-MD-Editor

    가장 먼저 React-MD-Editor를 사용해봤다.

    React-Md-Editor test

     

    하지만 이미지 업로드 버튼을 누르면 ![ ]( )만 생기는 현상이 발생했다.

     

     

    계속해서 React-Md-Editor의 이미지 업로드에 대한 내용을 찾아봤지만  React-Md-Editor가 왠지 모르게 구글에 찾아보아도 레퍼런스와 해결법이 잘 나와 있지 않았다. 그나마 찾은 방법이 React-Md-Editor의 깃헙 이슈에 있는 내용이었다.(https://github.com/uiwjs/react-md-editor/issues/83) 이 중에서 Drag&Drop으로 예제를 구현 해놓으신 분이 계셔서 코드를 살펴 보기로 했다.(https://codesandbox.io/s/react-md-editor-d-d-ihwzqm?file=/src/onImagePasted.tsx) 이미지를 URL.createObjectURL()을 사용하여 데이터를 보내고 저장하는 방식이었다. 무슨 형태인가 MDN (https://developer.mozilla.org/ko/docs/Web/API/URL/createObjectURL)을 살펴보니 객체를 가리키는 url을 DOMstring으로 바꾼다고 되어있다. 같은 객체라도 매번 다른 객체를 생성하며 메로리에 저장되고 객체를 생성한 창의 document가 사라지면 객체도 삭제된다고 되어있다. 지금 생각해보면 이걸 사용했어도 되지 않았나라는 생각이 들지만 당시에는 사라진다라는 단어가 사용되어 꺼려한 것 같다.

     

    3.2 ckEditor

    다음은 ckEditor가 레퍼런스가 많다고하여 써보기로 했다! 방식은 다음 블로그를 참고 했다. https://sloth.tistory.com/55

     

    [Spring Boot] CKEditor 이미지 업로드 구현하기

    게시판을 이용할 때 글씨에 색을 변경하고 이미지도 업로드하여 게시글을 작성합니다. 이것을 위지윅 에디터(WYSIWYG Editor)라고 하는데, 저는 무료 위지윅 에디터인 CKEditor를 이용하여 Spring Boot에

    sloth.tistory.com

    ckEditor는 위와 같이 생겼으며 몇가지 어려움이 발생했다.

     

    • 많은 레퍼런스 자체가 우리 환경과 맞지 않는 코드들이다.(대체로 백엔드 분들이 많이 블로깅 하심. => React에 대한 내용이 거의 없다)
    • 있다고 해도 이미지 업로드 탭 중에서 업로드가 존재 했지만 나의 ckEditor는 없었다.

     

    이미지 업로드 버튼을 눌러보았다.

     

     

    위와 같은 모달창이 뜨며 위에 탭이 2개가 있다. 저기에 업로드 라는 탭이 있어야 url을 사용하지 않고 바로 서버에 전송할 수 있다. 업로드 탭을 활성화하기 위해서 에디터 태그에 config속성의 filebrowserImageUploadUrl : 'Server url'을 추가해주면 된다. 지금 프로젝트는 리액트 환경에서 사용하고 있는데 리액트 환경에서 filebrowserImageUploadUrl를 다루는 내용이 존재하지 않아서 속성의 내용 따로 조사(http://ankyu.entersoft.kr/lecture/ASP/ckeditor_02.asp)하고 리액트에 config 적용하는 법(https://apollonius.tistory.com/208)을 따로 조사했다.

     

    import React from "react";
    import { CKEditor } from "ckeditor4-react";
    
    function App() {
      return (
        <div className="App">
          <h2>Using CKEditor 4 in React</h2>
          <CKEditor
            initData="<p>Hello from CKEditor 4!</p>"
            onInstanceReady={() => {
              alert("Editor is ready!");
            }}
            config={{    // config 내용 추가
            filebrowserUploadMethod :'form',
            filebrowserImageUploadUrl: "http://localhost:3001/data" 
            }}
          />
        </div>
      );
    }
    
    export default App;

     

    위의 config 속성을 추가하니 위와 같이 업로드 탭이 생겼다. 기본적으로 데이터를 JSON형식으로 전송하기 때문에 formdata로 전송하기위해 config 속성 filebrowserUploadMethod :'form'을 추가해 주었다. 데이터 통신을 테스트하기 위해서 json-server를 사용하여 통신을 진행해봤다.

    몇 번을 찍어 봐도 이와 같이 나왔다. 그래서 개발자 도구에 있는 네트워크 탭도 확인해 봤다.

     

    사이트에 나와있는 데모와 확인 해보니 잘 전달은 되는 것 같은데 왜 값이 저장이 안되나 생각해봤는데 json-server의 한계인 것 같았다. 백엔드 분께 물어보니 임시 서버를 열어 드릴테니 확인해보자고 하셨다!

     

    근데 바로 에러가 떠버린다. 구글링을 해보니 부모 창과 모달의 창이 주소가 달라서이라고 하는데 내가 직접 모달창을 구현한게 아니어서 모달창의 주소를 건드릴수가 없어고 어떤 데이터를 어떻게 보내는지 보고 조작할 수 없어서 포기...

     

    그러면 직접 이미지를 보내는 ckEditer에서 로직을 짜보자라고 생각해서 찾아보니 커스텀 플러그인이 있었다. 그런데 react 환경에서는 node_module안에 있는 폴더에 작성을 해야했다. 하지만 여기에 작성을 하면 gitHub으로 팀원과 공유할 때 적용되지 않는다. gitHup에 node_module은 올라가지 않기 때문이다. 이것 또한 포기...

    3.3 Toast UI

    데이터를 내가 직접 구성해서 보내는게 좋다고 생각하며 전체적인 텍스트 에디터에 대한 구글링을 해봤다. 가장 적절한텍스트 에디터가 Toast UI였다. 

    https://curryyou.tistory.com/474

     

    [React] Toast-UI Editor 이미지 파일 서버 업로드 방법 (base64 인코딩 X)

    # Toast-UI Editor 이미지 파일 서버 업로드 방법 일반적으로 이미지를 관리하는 방식은 첨부 이미지 파일은 서버 디스크에 저장해두고, 해당 경로만 DB에 저장해두는 것이다. 그러나 Toast-UI Editor 에

    curryyou.tistory.com

    위의 블로그는 이거면 가능하겠다라고 생각을 하게 해준 블로그이다.

     

    Toast UI에서 hook 속성 중 addImageBlobHook을 사용해 이미지를 전송하는 함수를 작성할 수 있다!

    <Editor
            ref={editorRef} 
            initialEditType="wysiwyg" 
            hideModeSwitch={true} 
            hooks={{
              addImageBlobHook: async (blob, callback) => {
                const formData = new FormData();
                formData.append("file", blob);
                const img = await axios.post(
                  "통신 url",
                  formData
                );
                const url = img.data[0].boardImageUrl;
    
                callback(url, "");
              },
            }}
          />

    Editor라는 태그 안에 hooks속성에 addImageBlobHook을 사용해 이미지를 전송하는 함수를 작성하는데 데이터의 형태가 blob이었다.(React-Md-Editor를 사용할 때 봤던 형태, 하지만 몇 시간, 몇 번의 실패로 정신이 피폐해져 이제와서야 앎) 그래서 데이터 형태를 formdata로 바꾸어 전송해주기 위해 formdata를 새로 생성해주는 함수를 사용하여 만들고 거기에 데이터를 넣어줬다. 처음에는 성공하는지 모르니 json-server로 테스트를 해봤는데 ckEditor와 같은 현상이 발생했고 다시 백엔드 분과 테스트를 했다. 그러자 테스트하기 위해 제공된 데이터가 들어오는걸 확인했다.! 드디어 몇 시간, 몇번의 실패에서 성공을 거머쥐었다.

     

    *출처

    React-Md-Editor

    https://github.com/uiwjs/react-md-editor/issues/83

    ckEditor
    http://ankyu.entersoft.kr/lecture/ASP/ckeditor_02.asp
    https://sloth.tistory.com/55
    https://apollonius.tistory.com/208

    toast
    https://velog.io/@moonelysian/Toast-UI-Editor
    https://curryyou.tistory.com/474

    'project > main' 카테고리의 다른 글

    10일 차 (무한 스크롤 구현)  (0) 2023.03.16
    9일 차 (모달창 반응형 + 모달창 페이지 전환)  (0) 2023.03.15
    7일차  (0) 2023.03.13
    5일차  (0) 2023.03.09
    3일차  (0) 2023.03.08
Designed by Tistory.