quill js editor 이미지 붙혀넣고 서버에 저장하고 quill editor에 서버에 저장한 이미지로 이미지 바꿔치기

Jaewoong2·2020년 7월 24일
1

boilerplate

목록 보기
5/13

quill js editor 이미지 붙혀넣고 서버에 저장하고 quill editor에 서버에 저장한 이미지로 이미지 바꿔치기

제목 그대로, quill js editor에 이미지 붙혀넣기를 할 때를 이용해보겠어요~~

이미지를 외부에서 복사해서 붙혀넣기를 하면 quill에서는 자동으로 base64 형태로 이미지를 binary로 저장 해줍니다.

이것을 my-sql로 저장하게 되면, 우리의 content 및 image는 TEXT 이 기 때문에, base64 형태로 저장된 이미지는 너무 길어서(너무 커서) 저장이 어렵습니다.

그래서 생각한 방법이 일단 붙혀넣기를 하면

  • Blob 형태의 파일로 저장한다
  • 그 파일을 FormData로 변환 후
  • 이미지 저장하듯이 처리해준다.
  • 그리고 앞 게시글에서 하였듯이, 서버에서 이미지 url을 받고 그 url을 quill innerhtml에 직접적으로 넣어줍니다
  • 그리고 base64형태의 이미지는 자동으로 없애줍니다
  1. base64형태의 img태그의 src를 찾는 함수를 만들어 줍니다.

const searchSrc = (root) => {
  const arr1 = root.split('img').map(v => v.includes('src') === true && v.split("src="));
  const arr2 = arr1.map(v => v && v[1]?.split("></p"))
  return arr2.map(v => v && v[0].slice(1, v[0]?.length - 1)).filter(v => v !== false);
} // "data:image/png;base64~~~"
searchSrc(quillInstance?.current?.root?.innerHTML).map((v, i) => { 
          if(v?.length > 1000) { //  "data:image/png;base64~~~"는 1000자를 넘어가기 때문에 + base64만 가져오기 위해서
              const imgBase64 = v;
              const file = DataURIToBlob(imgBase64);
          }
        })
  1. base64형태의 url 을 Blob형태로 바꿔줍니다
function DataURIToBlob(dataURI) {
  const splitDataURI = dataURI.split(',')
  const byteString = splitDataURI[0].indexOf('base64') >= 0 ? atob(splitDataURI[1]) : decodeURI(splitDataURI[1])
  const mimeString = splitDataURI[0].split(':')[1].split(';')[0]
  const ia = new Uint8Array(byteString.length)
  for (let i = 0; i < byteString.length; i++)
      ia[i] = byteString.charCodeAt(i)

  return new Blob([ia], { type: mimeString })
} // 출처 stackoverflow
  1. FormData형태로 이미지를 서버에 보내줍니다
const file = DataURIToBlob(imgBase64);
              const formData = new FormData();
              const nameMaking = `${Math.floor(Math.random() * 3000)}` + '_' + `${new Date().getTime()}`;
              formData.append('image', file, nameMaking); //3번째는 filename
              dispatch({
                type : UPLOAD_IMAGES_REQUEST,
                data : formData
            })
  • 이렇게하면 서버에서 이미지가 넘어옵니다
  • 이미지 받게 되면 base64 형태의 이미지는 지워줍니다
 searchSrc(quillInstance?.current?.root?.innerHTML).map((v, i) => {
            if(v?.length > 1000) {
              const innerHTML = Base64toServerImage(quillInstance?.current?.root?.innerHTML);
              quillInstance.current.root.innerHTML = innerHTML;
            }
          })
        }

function Base64toServerImage(fullstring) {
  const changeStr = fullstring.split('>').map(v => { 
    if(v.includes("<p")) {
     return v + '>'
   } else if(v.includes("</p")) {
   return v + '>'
   } else if(v.includes("<img")) {
     return false
   } else {
   return false
   } } ).filter(v => v !== false).join('')

   return changeStr
} // <p><img ~~~/></p> => <p></p>

이러면 성공~1

profile
DFF (Development For Fun)

2개의 댓글

comment-user-thumbnail
2021년 3월 3일

네~ jw님 도움이 많이 되었습니다! 그러나 한 가지 질문이 있는데요~ 사진 한 장 올렸을 때는 별 문제없는데 에디터에 여러 장 올릴 때는 InvalidCharacterError: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.가 뜨더라구요~

const DataURIToBlob = (dataURI) => {
const splitDataURI = dataURI.split(',');
console.log(dataURI);
const byteString = splitDataURI[0].indexOf('base64') >= 0 ? atob(splitDataURI[1]) : decodeURI(splitDataURI[1])
const mimeString = splitDataURI[0].split(':')[1].split(';')[0]
const ia = new Uint8Array(byteString.length)
for (let i = 0; i < byteString.length; i++)
ia[i] = byteString.charCodeAt(i)

      return new Blob([ia], { type: mimeString })
  };

이 쪽에서 atob에 문제가 생긴 거 같은데 해결방법이 있나요~?

1개의 답글