Cloudflare R2 이미지 URL 표시 문제: 상세 설명 및 해결 방법

도메인 설정이 포함된 업데이트된 테마 컴포넌트로 이 문제를 해결했습니다. 이제 누구나 자체 컴포넌트를 하드코딩하지 않고도 이를 사용할 수 있습니다. 이는 모든 S3 호환 저장소에서 작동합니다:

직접 패치하는 경우, 이니셜라이저는 다음과 같이 작성해야 합니다
import { apiInitializer } from "discourse/lib/api";

export default apiInitializer("1.8.0", (api) => {

  // ⚠️ 이 도메인이 정확히 여러분의 도메인인지 확인하세요!
  // 게시글 썸네일 및 채팅 썸네일의 이미지 경로를 확인하고 비교해 보세요!

  const badDomain = "yoursite-uploads.xxx.r2.cloudflarestorage.com";
  const goodDomain = "uploads.yoursite.com";

  function fixImage(img) {
    if (img.src && img.src.includes(badDomain)) {
      img.src = img.src.replace(badDomain, goodDomain);
    }
    if (img.dataset?.src && img.dataset.src.includes(badDomain)) {
      img.dataset.src = img.dataset.src.replace(badDomain, goodDomain);
    }
  }

  // 1. 표준 게시글/HTML에서 렌더링된 이미지를 안전하게 수정
  api.decorateCooked($elem => {
    const container = $elem[0];
    if (!container) return;
    
    container.querySelectorAll(`img[src*="${badDomain}"]`).forEach(fixImage);
  }, { id: 'fix-r2-chat-bug' });

  // 2. 동적으로 주입된 채팅 요소에만 적용되는 고성능 옵저버
  const observer = new MutationObserver(mutations => {
    for (const mutation of mutations) {
      
      // 새 채팅 메시지나 요소가 DOM에 주입된 경우
      if (mutation.type === 'childList') {
        for (const node of mutation.addedNodes) {
          if (node.nodeType === 1) { // ELEMENT_NODE
            if (node.tagName === 'IMG') fixImage(node);
            
            // 새 노드 내부에서만 검색하며, 문서 전체를 검색하지 않음
            node.querySelectorAll(`img[src*="${badDomain}"]`).forEach(fixImage);
          }
        }
      } 
      // 기존 이미지의 src 속성이 변경된 경우 (레이지 로딩)
      else if (mutation.type === 'attributes') {
        if (mutation.target.tagName === 'IMG') {
          fixImage(mutation.target);
        }
      }
    }
  });

  // 옵저버를 즉시 시작
  observer.observe(document.body, {
    childList: true,
    subtree: true,
    attributes: true,
    attributeFilter: ['src', 'data-src']
  });
});
3개의 좋아요