JavaScript/XMLHttpRequest - Velog RSS 활용 게시물 불러오기

이승현·2023년 12월 29일
0

Javascript

목록 보기
4/6
post-thumbnail

Velog 포스팅을 웹 페이지에 업로드하고 싶다면 다양하게 적용할 수 있다.
링크나 게시글에 대해 직접 받아와서 적용할 수도 있겠지만 계속 추가되는 게시물이 생길때마다 업로드해주어야 하는 불편함이 있다.

따라서 Velog 페이지에서 포스팅에 대한 정보를 받아와 적용하는 방법이라면 게시물이 자동으로 업데이트 되는 효과를 볼 수 있다.

RSS

RSS란?
게시물과 같은 콘텐츠를 이용하는데 해당 게시물에 직접 접근하지 않고도 그 정보를 얻을 수 있는 방식이다.
뉴스와 같은 정보를 받기 위해 일일이 페이지들을 방문하게 된다면 필요 이상의 데이터를 처리해야 한다. 사용자들을 위해 추가적으로 적용된 디자인과 기능들이 포함되기 때문이다. 하지만 RSS와 같은 기능을 이용한다면 필요 정보를 효율적으로 처리할 수 있게 된다.

https://v2.velog.io/rss/벨로그아이디
해당 rss는 벨로그에서 게시글에 대해 xml을 반환하는 방법이다. 잘 파싱하면 게시글에 사용할 수 있지만 가장 큰 단점은 "썸네일은 포함되지 않는다"는 점이다.

벨로그에 대한 기본 정보와 링크등 다양한 데이터들을 받을 수 있다. 게시글 이미지를 포함해 각 게시글에 대한 정보를 <item> 태그에 넣어서 제목과 경로, 날짜, 글 내용이 들어가있다.

JavaScript에서 이를 받아서 처리해보자.

1. XMLHttpRequest

XMLHttpRequest는 JavaScript에서 xml형식을 처리하는 기능이다.

// xhr라는 요청 변수 생성
const xhr = new XMLHttpRequest();

// xhr에 요청에 대한 메서드와 대상 주소값을 의미한다.
xhr.open(메소드,대상url);

// xhr의 요청이 완료된 경우에 기능을 작성
xhr.onload = () =>   {
  처리 기능	
};

// 기능 실행!
xhr.send();  

이러한 코드로 기본적인 처리가 가능하지만 여기까지만 알면 재미가 없다.
좀더 들여다보면 다음과 같다.

XMLHttpRequest으로 요청을 생성한 이후에는 상태가 계속 변하게 된다.
xhr.UNSENT : 최초 생성시
xhr.OPENED : open 실행시
xhr.HEADERS_RECEIVED : setRequestHeader 실행시
xhr.LOADING : send후 결과값이 돌아오기 전까지
xhr.DONE : 결과값이 도착했을 경우

이러한 값은 xhr.readyState로 확인할 수 있다.

때문에 DONE의 상태에서 성공, 실패의 기능을 처리하고 싶다면 onloadonerror와 같은 기능을 사용할 수 있다.
이때 각 상태 변화에 대해 계속 반응하기 위한 함수가 onreadystatechange에 해당한다.

xhr.onreadystatechange = () =>   {
  if (xhr.readyState === xhr.UNSENT) {
    최초 생성
  }
  if (xhr.readyState === xhr.OPENED) {
    open 생성
  }
  if (xhr.readyState === xhr.HEADERS_RECEIVED) {
    헤더 생성
  }
  if (xhr.readyState === xhr.LOADING) {
    실행
  }
}

다음과 같은 방식으로 작동하는 방법도 있다.
자세한건 아래 링크를 확인해보자. 다양한 XMLHttpRequest관련 함수를 볼 수 있다.
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/error_event

이를 기반으로 코드르 생성하면 다음과 같다.

// 페이지 접근시 기능 실행
window.onload = function(){
  // XMLHttpRequest 객체 생성
  const xhr = new XMLHttpRequest();
  
  // XMLHttpRequest 메서드와 대상 링크 설정
  const method = "GET";
  const url = "https://api.velog.io/rss/@dltmdgus9661"
  // 요청 생성
  xhr.open(method, url);
  // xhr이 요청이 완료된 경우 결과를 생성
  xhr.onload = () =>   {
    // 결과 값은 response를 통해 저장
    var data = xhr.response;     
    //xml 값을 파싱으로 분할
    let xmlDocs = new DOMParser().parseFromString(data,"text/xml");
    // 각 item을 태그 이름으로 검색
    items = xmlDocs.getElementsByTagName("item");
    // item을 반복문을 통해 접근
    for(let item of items){
      // 각 태그와 그 내부 내용을 받을 수 있다.
      for(let child_node of item.children) {
        console.log(child_node.tagName);
        console.log(child_node.textContent);
      }
    }
  };
  // XMLHttpRequest 실행!
  xhr.send();  
} 

2. 썸네일 이미지

여전히 썸네일 이미지는 포함되어 있지 않아 가져올 방법이 없다.
그렇다면 포기해야하나 고민하던 그때....

띠용하고 떠오른 방법이 바로 hidden type의 Input을 활용하는 방법!

  • 벨로그에 <input type="hidden>으로 썸네일 url을 넣는다.
  • RSS는 글의 원문을 가져온다.
  • 가져온 원문에서 input값을 가져와 썸네일 url을 찾아낸다!

이러한 기반 내용을 적용하면 다음과 같은 함수를 생성할 수 있다.

// 썸네일과 설명문을 구하는 함수
function getThumnail(str){
  // 요청 결과에서 글 내부 내용을 받아와 html 형식으로 파싱
  description = new DOMParser().parseFromString(str,"text/html");
  // Input DOM을 찾아 value에서 썸네일 url을 가져온다.
  input = description.getElementsByTagName("input")[0];
  try {
    thumnail = input.value;
    //썸네일이 없는 경우 대체 이미지 추가
  } catch (err) {
    thumnail="assets/img/velog.png";
  }
  // 나머지는 텍스트만 뽑아와 보조 설명으로 추가
  desc = description.getElementsByTagName("body")[0].textContent.substr(0, 200);
  return [desc,thumnail]
}    

해당 내용들을 받는 함수는 다음과 같이 적용할 수 있다.

// 페이지 접근시 기능 실행
window.onload = function(){
  // XMLHttpRequest 객체 생성
  const xhr = new XMLHttpRequest();
  
  // XMLHttpRequest 메서드와 대상 링크 설정
  const method = "GET";
  const url = "https://api.velog.io/rss/@dltmdgus9661"
  // 요청 생성
  xhr.open(method, url);
  // xhr이 요청이 완료된 경우 결과를 생성
  xhr.onload = () =>   {
    // 결과 값은 response를 통해 저장
    var data = xhr.response;     
    //xml 값을 파싱으로 분할
    let xmlDocs = new DOMParser().parseFromString(data,"text/xml");
    // 각 item을 태그 이름으로 검색
    items = xmlDocs.getElementsByTagName("item");
    // item을 반복문을 통해 접근
    for(let item of items){
      // 각 태그와 그 내부 내용을 받을 수 있다.
      for(let child_node of item.children) {
        if(child_node.tagName == "description"){
          //게시글 내용인 경우 썸네일과 내부 텍스트를 반환
          getThumnail(child_node.textContent);
        }else{
        }
        console.log(child_node.tagName);
        console.log(child_node.textContent);
      }
    }
  };
  // XMLHttpRequest 실행!
  xhr.send();  
} 

해당 내용들을 Javascript 단계에서 필요한 곳에 넣어주면 된다!

0개의 댓글