data uri scheme 으로 웹페이지에 리소스 인라인 첨부
동적으로 생성한 ics 파일 컨텐츠를 다운로드할 수 있게 하기 위해 data uri 를 써서 리소스를 인라인으로 넣었는데, 대충 써오던거를 자세히 알아보고자 좀더 조사해봄.
참고 문서
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
- https://en.wikipedia.org/wiki/Data_URI_scheme
형식
data:[<mediatype>][;base64],<data>
ics 를 넣고자 한다면
data:text/calendar,<data>
data 부분을 base64 인코딩했으면 ;base64
라는 구문이 들어가야하고, text 인 경우에는 base64 할 필요는 없이 encodeURIComponent()
로 인코딩해서 넣으면 된다.
그리고 <data>
영역 앞에 ,
를 빼먹으면 안됨.
실제 사용한 코드
ics.createEvent(calEvent, (error, value) => {
if (error) {
console.error(error);
} else {
const uriContent = "data:text/calendar," + encodeURIComponent(value);
const link = document.createElement("a");
link.text = "download ics";
link.download = `${title}.ics`;
link.href = uriContent;
link.className = "msg-button msg-button--clickable";
const insertHere = document.querySelector(".msg-button");
insertHere.parentNode.insertBefore(link, insertHere);
}
});
추가.
나중에 a 요소 생성하는 부분은 다음과 같이 바꾸었다. (의존성 있음)
ics.createEvent(calEvent, (error, value) => {
if (error) {
console.error(error);
} else {
const uriContent = "data:text/calendar," + encodeURIComponent(value);
const downloadLink = `
<a href="${uriContent}" download="${title}.ics" class="msg-button msg-button--clickable">download ics</a>
`;
const insertHere = document.querySelector(".msg-button");
insertHere.parentNode.insertBefore(userscript_util.html.htmlToElement(downloadLink), insertHere);
}
});