백엔드 : node.js
프론트엔드 : react.js
목표 :
로직 :
1) url입력 이벤트 발생
2) url데이터인지 확인
3) BackEnd API호출
4) 해당 url주소에서 OG데이터 추출
4-1) iframe이라면 해당 주소로 다시 http요청
5) OG데이터 기반 html태그 구성 후 return
사용라이브러리 :
//paste이벤트가 발생시 url데이터인지 확인하는 함수
const handlePaste = async (event) => {
const clipboardData = event.clipboardData || window.clipboardData;
const pastedData = clipboardData.getData("text");
const urlRegex = /^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/i;
if (urlRegex.test(pastedData)) {
event.preventDefault();
try {
setLoading(true);
const ogData = await makeNewLink(pastedData);
const ogHTML = ogData.data.data.data;
const updatedContent = content.replace(new RegExp(pastedData, 'g'), '') + ogHTML;
editorRef.current.getInstance().setMarkdown(updatedContent);
setLoading(false);
} catch (error) {
console.error("Failed to fetch OG data:", error);
}
}
};
//새로운 html태그를 요청하는 함수
const makeNewLink =async(url)=>{
const response = await axios.post(
`${백엔드API}/어쩌구/저쩌구`,
{url : url},
);
return response;
}
<div onPaste={handlePaste}>//Editor가 있는 태그에 이벤트를 붙여줍니다.
let url = req.body.url
const getImageFromURL = async (url) => {
try {
const response = await axios.get(url);
const data = response.data;
// Check if the data is wrapped in an iframe
const iframeRegex = /<iframe[^>]+src="([^">]+)/g;
const iframeMatch = iframeRegex.exec(data);
if (iframeMatch) {
const iframeDataArr = []
const iframeSrc = iframeMatch[1];
const iframeURL = 'http://blog.naver.com' + iframeSrc;
const iframeResponse = await axios.get(iframeURL);
const iframeData = iframeResponse.data;
const iframeResult = await ogs({ html: iframeData });
iframeDataArr.push(iframeResult.result.ogImage[0].url)
iframeDataArr.push(iframeResult.result.ogDescription)
return iframeDataArr;
}
} catch (error) {
console.log(error);
}
};
const makeLink = async (url) => {
try {
const urlData = [];
const options = {
url: url,
peekSize: 30000000,
};
const response = await axios.get(options.url);
const data = response.data;
const result = await ogs({ html: data });
urlData.push({ ...result.result, url: options.url });
let imageSrc = '';
let description ='';
if (urlData[0].ogImage && urlData[0].ogImage.length > 0) {
// ogImage가 존재하는 경우
imageSrc = urlData[0].ogImage[0].url;
description = urlData[0].ogDescription;
} else {
// ogImage가 없는 경우
const data = await getImageFromURL(options.url);
imageSrc = data[0];
description = data[1];
}
const newLink = `
<div class='newlink'>
<a href="${options.url}">
<img src="${imageSrc}" alt="${urlData[0].ogTitle}" referrerpolicy="no-referrer" crossOrigin="anonymous"/>
<h3>${urlData[0].ogTitle}</h3>
<p>${description}</p>
</a>
</div>`;
return newLink;
} catch (error) {
console.log(error);
}
};
const newLink = await makeLink(url);
url = newLink;
req.jsondata={data: url}
해당 코드는 일반적으로 OG데이터 를 포함한 웹페이지 혹은 네이버블로그에만 대응이 되기 떄문에 예외처리가 필요할 수 있습니다.