같은 이미지인데 미리보기가 이상하게 나온다고요?

모두가 알지만 가끔 깜빡하는 MIME 타입 이야기

이찬희
6 min readNov 15, 2020

최근에 어떤 서비스를 통해 Facebook에서 보여주는 링크의 미리보기 이미지를 바꾼 적이 있다. 그런데 링크 미리보기에서 계속 내가 의도하지 않았던 모양으로 나왔다. 이미지가 꽉 채워지고 아래에 설명이 나오는 형태를 생각했는데, 이미지가 정사각형으로 짤려나왔다 😇

갑자기 열받게 하는 미리보기 이미지

보통은 이미지 크기 때문에 이런 문제가 발생할 수 있다. 미리보기 이미지는 1200px * 630px, 그게 아니더라도 1.9:1의 비율을 맞춰줘야, 링크 미리보기에서 이미지가 꽉 채워져서 나온다.

그런데 이미지 사이즈는 정확히 1200px * 630px였다.
무엇이 문제일까?

  • og:image:widthog:image:height 를 주지 않아서? → 이는 링크 미리보기의 초기 정보를 구성할 때의 속도를 높여주는 부가 정보이지, 딱히 넣어주지 않아도 시간이 지나면 알아서 잘 된다.
  • og:typearticle 이 아니어서?og:typewebsite 로 된 다른 사이트들에서 문제가 없었다.
  • 이미지의 파일 타입이 png 여서? → 예전에 Facebook에 그런 버그가 아주 잠깐 있었는데 지금은 문제가 없다.
  • Facebook에서 머신러닝으로 이미지 정가운데에 콘텐츠가 안오면 저렇게 만들기로 정책을 바꿨다? → 비슷한 계열의 정책이 광고에 있긴 한데… 설마 🤯
  • Facebook에서 미리보기 이미지를 긁어가다 뻑이 났다?

문제의 실마리는 가장 마지막 가설을 확인해보다가 잡게 되었다.
가설의 검증을 위해 일괄 무효화 도구를 돌린 뒤 공유 디버거를 통해 다시 링크를 스크랩했다.

그랬더니 ‘해결해야 하는 경고’ 영역에 ‘링크 URL이 올바르지 않다’는 오류가 떴다.
이미지 자체는 깨지지 않았기에 S3에 이미지를 올려 URL을 만들었다. 그리고 그 URL을 og:image 에 적용하였다.

그 후에 다시 링크를 스크랩했더니 잘 뜬다
…?

처신 잘하라고

같은 이미지를 업로드했는데 다르게 뜰 수 있던가?
URL을 통해 이미지를 불러오니까, Header를 들여다보면 뭔가 차이가 있을 것이라고 생각했다. Postman을 사용해 요청을 날린 후에 Headers를 들여다보기로 했다.
(참고로, curl 써도 되긴 하는데 ‘GUI를 쓸 수 있을 때까지는 GUI를 쓰자는 주의’기 때문에 Postman을 사용했다)

각각 미리보기가 이상하게 뜨는 URL(위) / 정상적인 이미지를 제공하는 URL(아래)의 Headers다. 차이점이 보이는가?

미리보기 이미지가 이상하게 뜨는 URL
정상적인 미리보기 이미지를 제공하는 URL

몇몇 차이가 있겠지만, 가장 중요한 것은 Content-Type이다.
문제가 되는 URL에서는 binary/octet-stream 으로 뜨고,
정상적인 URL에서는 image/jpeg 로 뜬다.

Content-Type. 즉 MIME 타입¹이 잘못 설정되어 Facebook에서 해당 URL을 통해 이미지를 가져올 때 오류가 난 것으로 추측하였다.

MIME 타입 = 파일 해독을 위한 설명 정도로 생각을 하고 있다.

메일을 생각해보면, 글 뿐만 아니라 사진과 영상, 음악 등 다양한 파일을 업로드하고 다운로드할 수 있다. 각각의 파일은 0과 1로 구성되어 있다.

근데 메일은 텍스트를 보내는 방식이다. 그려면 보내는 쪽이 파일 → 텍스트로 바꿔주고, 받는 쪽에서 텍스트 → 파일로 바꿔주면 된다.
근데 만약에 ‘파일 → 텍스트로 바꾸는 방식’과 ‘텍스트 → 파일로 바꾸는 방식’이 다르면 어떻게 될까? 서로 파일을 못 열어보는 참사가 발생한다 🤬

여기서 MIME 타입이 등장한다. 서로 변환하는 과정에서 공통된 방식을 쓰되, 이 텍스트를 풀면 이미지가 나오는지, 사진이 나오는지, 아니면 그냥 다른 파일이 나오는지… 등의 설명을 달아주면 깨지지도 않고 텍스트만 받아도 파일로 바꿔볼 수 있다.

‘아하’ 정도만 해도 괜찮을 것 같다는 생각이 들어 가볍게 개념을 정리한다.

보통 이미지들은 MIME 타입에 image/png , image/jpeg 등으로 표현이 된다.
만약에 HTML을 조금 더 안다면 Input 태그의 type이 file일 때, accept="image/*" 처럼 파일 업로드 시 타입을 제한할 수 있다는 것과도 연관지을 수 있을 것이다.

그리고 문제가 되었던 MIME 타입인 binary/octet-stream 은 모르는 파일 타입들을 나타낼 때 쓴다. 텍스트도 아니고, 이미지도 아니고, 뭣도 아닌 친구들을 지칭할 때 이 녀석을 사용한다.

참고로, Chrome 같은 브라우저에서 MIME 타입이 binary/octet-stream 인 링크의 URL을 입력해서 들어가면 해당 파일이 다운로드 된다.
MIME 타입이 image/* 면? 그 파일이 그대로 보여지게 된다.

그냥 이렇게 보여지게 된다.

MIME 타입과 관련해서 보다 자세한 내용은 아래에서 참고할 수 있다.

어쨌든 이 문제를 해당 서비스에 알렸다. 아마 수 일 내로 해결되지 않을까.
갑자기 오랜만에 뜬금 없는 삽질을 했는데, 그래도 이렇게 흐릿했던 지식을 짚고 넘어갈 때 재미를 느끼곤 한다.

¹ Multipurpose Internet Mail Extension, 다목적으로 인터넷 메일을 확장.

--

--

이찬희

Building invisible things for visible one — Software Engineer @​AB180. Founder @​sullivanproject.