[Notion] 커스텀 도메인 이미지 오류 수정

2020. 9. 6. 11:20IT/Interest

나는 포트폴리오를 직접 만든 사이트를 통해 운영하다가 최근 Notion으로 모든 데이터를 이전했고 기존 운영하던 포트폴리오 사이트의 도메인을 Notion에 연결했다. 처음 Notion을 접했을 때는 단순한 메모 툴 정도로 여겼는데 Notion의 기능들을 활용하다 보니 가볍게 여길 서비스는 아닌 것 같다.
 

[Notion] 노션 공개 페이지에 도메인 연결하기

노션에서 작성한 모든 페이지는 공개 링크를 만들어 다른 사람에게 공유하거나 검색 엔진에 노출시킬 수 있다. 노션에 가입하지 않아도 누구나 방문할 수 있다는 말이다. 언제가 될진 모르겠지�

romantech.net

 

그러나 어느 날부터 포트폴리오 사이트 접속 시 이미지를 받아오지 못하는 오류가 발생하였고 로그를 확인해보니 URL의 GET 파라미터가 정상적으로 전달되지 않고 있다는 것을 파악했고 Worker의 스크립트를 수정하여 간단하게 해결했다.

 

(좌) 오류 페이지, (우) 정상 페이지

오류를 파악하기 위해 개발자 도구의 콘솔을 통해 오류 메시지를 파악하고 해당 이미지 링크로 직접 접속을 시도해보았다.

이미지 에러 콘솔 로그

접속을 해보니 table과 id 값이 있어야 한다는데 분명 링크를 보면 정상적으로 table과 id 값을 보내고 있다.

그렇다면 이 정보를 Notion으로 전달하는 worker에서 올바르게 처리가 되고 있지 않다고 판단했고 코드를 보니 내 판단이 맞았다.

Notion API 오류 메세지

아래 코드는 fetchAndApply 함수 내부의 조건문인데 지정 된 조건에 걸리지 않는 경우는 모두 아래 부분에서 처리한다.

기존 response를 받아오는 경로는 'https://www.notion.so${url.pathname}' 이었는데 나는 GET 파라미터를 넘겨주기 위해 ${url.search}를 추가로 붙여주었다.

수정 된 코드

수정된 Worker 스크립트는 아래와 같고 본문 상단에 링크된 페이지의 순서를 따라 설정을 한 뒤, MY_DOMAIN과 START_PAGE를 본인에게 맞게 수정하면 된다.

const MY_DOMAIN = "연결 할 도메인"
const START_PAGE = "노션 링크"

addEventListener('fetch', event => {
  event.respondWith(fetchAndApply(event.request))
})

const corsHeaders = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Methods": "GET, HEAD, POST,PUT, OPTIONS",
  "Access-Control-Allow-Headers": "Content-Type",
}

function handleOptions(request) {
  if (request.headers.get("Origin") !== null &&
    request.headers.get("Access-Control-Request-Method") !== null &&
    request.headers.get("Access-Control-Request-Headers") !== null) {
    // Handle CORS pre-flight request.
    return new Response(null, {
      headers: corsHeaders
    })
  } else {
    // Handle standard OPTIONS request.
    return new Response(null, {
      headers: {
        "Allow": "GET, HEAD, POST, PUT, OPTIONS",
      }
    })
  }
}

async function fetchAndApply(request) {
  if (request.method === "OPTIONS") {
    return handleOptions(request)
  }
  let url = new URL(request.url)
  let response
  if (url.pathname.startsWith("/app") && url.pathname.endsWith("js")) {
    response = await fetch(`https://www.notion.so${url.pathname}`)
    let body = await response.text()
    try {
      response = new Response(body.replace(/www.notion.so/g, MY_DOMAIN).replace(/notion.so/g, MY_DOMAIN), response)
      // response = new Response(response.body, response)
      response.headers.set('Content-Type', "application/x-javascript")
      console.log("get rewrite app.js")
    } catch (err) {
      console.log(err)
    }

  } else if ((url.pathname.startsWith("/api"))) {
    response = await fetch(`https://www.notion.so${url.pathname}`, {
      body: request.body, // must match 'Content-Type' header
      headers: {
        'content-type': 'application/json;charset=UTF-8',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
      },
      method: "POST", // *GET, POST, PUT, DELETE, etc.
    })
    response = new Response(response.body, response)
    response.headers.set('Access-Control-Allow-Origin', "*")
  } else if (url.pathname === `/`) {
        let pageUrlList = START_PAGE.split("/")
    let redrictUrl = `https://${MY_DOMAIN}/${pageUrlList[pageUrlList.length-1]}`
    return Response.redirect(redrictUrl, 301)
  } else {
    response = await fetch(`https://www.notion.so${url.pathname}${url.search}`, {
      body: request.body, // must match 'Content-Type' header
      headers: request.headers,
      method: request.method, // *GET, POST, PUT, DELETE, etc.
    })
  }

  return response
}