이미지 넣고 수정하기
프론트엔드에서 이미지를 보여주기 위해서는 해당 이미지의 url 정보나 base64로 인코딩 된 값이 필요했다. 하지만 방금 막 업로드한 이미지의 url은 서버에 저장되어 있지 않고, 클라이언트에서 임시로 url을 만들어 보여주는 단순 미리보기 기능밖에 구현이 되지 않는...
이미지 삽입 문제
프로젝트 설계 당시부터 나온 이슈 중 하나는 게시글 중간에 이미지를 어떻게 삽입할 것인가였다. 대부분의 게시판을 이용하는 서비스들은 이미지를 텍스트 중간에 넣을 수 있도록 만들어져 있었고, 우리가 만들고 있는 이 서비스 역시 그런 기능을 추가해야 한다고 생각했다. 하지만, 해당 문제를 해결하기 위해서 나온 여러 방안은 하나씩 문제가 있었다.
프론트엔드에서 이미지를 보여주기 위해서는 해당 이미지의 url 정보나 base64로 인코딩 된 값이 필요했다. 하지만 방금 막 업로드한 이미지의 url은 서버에 저장되어 있지 않고, 클라이언트에서 임시로 url을 만들어 보여주는 단순 미리보기 기능밖에 구현이 되지 않는다.
그렇다면 어떻게 게시글 작성 후 이미지를 불러와서 보여줄 수 있을까?
방안 1) 에디터를 사용한다.
가장 쉬운 해결 방법은 기존에 나온 에디터를 사용하는 것이라고 생각한다. 에디터 자체에는 여러가지 기능들이 이미 구현되어 있고, 이미지를 텍스트 중간에 삽입할 수 있도록 기능이 구현되어 있다. 하지만 단점이 존재했다. 바로 해당 이미지가 base64로 인코딩 되어 삽입이 되거나, 이미 존재하는 url을 마크다운처럼 삽입하는 방식이 대부분이었다.
여기서 base64로 인코딩되면 문제 해결이 되는 것이 아닐까 할 수 있지만, 다른 문제가 발생할 수 있다. base64의 경우 이미지 크기가 커지면 인코딩된 문자가 길어지게 되고 그것 자체를 데이터베이스에 담는 것은 효율적이라고 생각되지 않았다. 또한, 코드로 보았을 때도 인코딩된 문자가 길면 코드를 읽는데 어려움이 있을 수 있을 것이라 생각했기 때문에 해당 방법은 제외시켰다.
방안 2) s3에 저장 후 이미지 url이용
제일 좋은 방법이라고 생각한 것은 사용자가 이미지를 업로드 하자마자 s3에 해당 이미지를 등록하고 바로 url을 받아와서 src속성에 넣은 후 img태그 자체를 다른 텍스트와 같이 데이터베이스에 넣는 방법이었다. 실제 velog의 방식을 보면 이미지를 드래그 앤 드롭 했을 때 바로 서버 요청이 있고, url을 받아오는 것을 확인할 수 있다. 아마 비슷한 방식이 아닐까했다. 하지만 이 방법도 완전하진 않았다. s3에 이미지를 저장하는 것 자체가 네트워크 요청이 필요한 작업이었고, 이로 인해서 사용자는 약간의 딜레이를 느낄 수 있다는 문제와 게시글 작성 중에 삽입한 이미지를 지울 수 있기 때문에 반복적인 네트워크 요청이 있을 수 있다는 점이 문제였다. 그래도 큰 문제는 아니라고 판단이 된다. 대신 다른 문제는 어쨌든 이미지를 텍스트 형식으로 데이터베이스에 저장하고 불러오는데, 이를 클라이언트에서 보여주기 위해서는 innerHTML을 이용하는 방법이 제일 편하다고 생각한다. 하지만 이 방법은 보안의 위협이 있는 방법이므로 완전한 방법이 아니라고 생각했다.
방안 3) 이미지 삽입 위치를 표시한다.
게시글 작성자가 이미지를 중간에 삽입하면 미리보기를 보여준 뒤 해당 위치를 특정 문자(게시글은 텍스트 형식이기 때문에)로 표시를 하는 방법을 생각했다. 이 방법의 문제는 사용자가 의도치 않게 이미지를 표시하는 문자를 썼을 경우 원치 않는 위치에 이미지가 보여질 수 있다는 문제가 있다. 이에 대해 얻은 다른 아이디어는 표시를 하는 것을 문자로 하지 말고 객체 형식으로 (json 형식의 데이터가 저장될 것이니까) 표시 위치를 기억하는 방법이었다. 괜찮은 방법이라고 생각하고 충분히 활용 가능할 수 있다고 생각했다.
현재 적용은?
현재는 이미지를 게시글 중간에 삽입하는 기능을 넣지 않았다. 이는 위에서 말한 방법들의 문제를 완벽히 해결하지 못하고 있기 때문이다. 또한, 백엔드에서 s3에 이미지를 저장하는 방식을 단순히 게시글 작성 버튼을 눌렀을 때 텍스트와 이미지를 저장하는 식으로 api를 구성했기 때문에 게시글 맨 마지막에 이미지가 삽입되도록 구현되어 있다.
추후에는 파이어베이스를 이용해서 이미지를 중간에 삽입하도록 구현해볼까 한다. 방안2를 파이어베이스로 구현한다고 생각하면 된다. 또한 추후에 innerHTML에서 보안의 위협이 개선된 setHTML() 메소드가 나올 예정이므로 보안 위협은 어느정도 해결이 될 수 있다고 생각이 된다.