Orbit

엣지 함수

Edge functions are small JavaScript handlers that run on Kapsule's edge network before a request reaches your project, so you can do redirects, header injection, A/B routing and bot filtering…

Edge functions는 요청이 프로젝트에 도달하기 전에 Kapsule의 엣지 네트워크에서 실행되는 작은 JavaScript 핸들러이므로, 앱에 왕복하지 않고도 리다이렉트, 헤더 주입, A/B 라우팅 및 봇 필터링을 수행할 수 있습니다. 이 가이드는 함수 작성, 허용되는 진입점 형식, 경로 매칭, 여러 함수의 상호작용, 배포 및 함수에서 예외가 발생했을 때의 동작을 다룹니다.

위치

Orbit에서 프로젝트를 열고 Edge functions 탭을 클릭합니다. 모든 함수는 프로젝트에 속하며 상태 배지와 함께 나열됩니다: LIVE, PAUSED, NOT DEPLOYED 또는 DEPLOY FAILED.

Orbit 프로젝트의 Edge functions 탭

함수 만들기

  1. New function을 클릭합니다.
  2. Name을 입력합니다(최대 120자).
  3. Path pattern을 입력합니다. 이 함수가 실행되어야 하는 URL 패턴입니다.
  4. Trigger를 선택합니다: Request (origin 전), Response (origin 후) 또는 Both.
  5. Environment scope를 선택합니다: All environments, Production only 또는 Preview only.
  6. Function body에 핸들러를 작성합니다.
  7. Save를 클릭한 후 Deploy to edge를 클릭합니다.

request 객체는 항상 범위에 있으며, 소스는 64 KB로 제한됩니다.

핸들러 작성

엣지에서 요청에 응답하려면 Response를 반환합니다. 요청을 프로젝트에 변경 없이 전달하려면 아무것도 반환하지 않거나 undefined을 반환합니다.

export default {
  async fetch(request) {
    const url = new URL(request.url)

    // Redirect /old to /new
    if (url.pathname === '/old') {
      return new Response(null, {
        status: 301,
        headers: { Location: '/new' },
      })
    }

    // Returning nothing passes through to the origin
  },
}

명명된 함수 형식도 작동합니다:

export default async function handler(request) {
  // Add a security header to every response
  const response = await fetch(request)
  const headers = new Headers(response.headers)
  headers.set('X-Frame-Options', 'DENY')
  return new Response(response.body, { status: response.status, headers })
}

지원되는 진입점 형식

형식
fetch 메서드가 있는 객체export default { async fetch(request) { ... } }
화살표 fetch 속성이 있는 객체export default { fetch: async (request) => { ... } }
명명된 함수 선언export default async function handler(request) { ... }
래퍼 없는 본문만래퍼 없이 명령문을 직접 작성합니다

export default를 사용하는 다른 모든 것(예: export default class)은 저장을 클릭할 때 거부되며, 대신 사용할 두 가지 형식의 이름을 지정하는 오류가 표시됩니다. 유효성 검사는 배포 시간이 아닌 저장 시간에 실행되므로 즉시 알 수 있으며 손상된 함수는 절대 게시되지 않습니다.

경로 패턴

Path pattern은 함수를 실행할 요청을 결정합니다. /로 시작해야 하며 최대 2048자일 수 있습니다. *는 모든 문자 실행과 일치하고 ?는 단일 문자와 일치합니다. 와일드카드가 없는 패턴은 정확히 그 경로 및 아래의 모든 항목과 일치합니다.

패턴일치
/*모든 경로
/api/*/api/로 시작하는 모든 항목
/blog/*/comments예를 들어 /blog/my-post/comments
/page/page/page/ 아래의 모든 항목

request 객체

request는 표준 Fetch API Request입니다. URL, 메서드, 헤더 및 본문을 읽을 수 있습니다:

export default {
  async fetch(request) {
    const url    = new URL(request.url)
    const cookie = request.headers.get('cookie') ?? ''
    const ua     = request.headers.get('user-agent') ?? ''

    if (ua.includes('BadBot')) {
      return new Response('Forbidden', { status: 403 })
    }
  },
}

다른 플랫폼에서 본 헤더가 있다고 가정하지 마십시오. 함수가 실제로 받는 헤더를 읽으십시오(함수에서 로그하거나 일회용 경로에서 디버그 응답으로 반환). 헤드없는 헤더에 따라 분기하는 핸들러는 모든 요청에서 자동으로 잘못된 경로를 따릅니다.

일반 패턴

이전 URL 리다이렉트

export default {
  async fetch(request) {
    const url = new URL(request.url)
    const redirects = {
      '/old-about':   '/about',
      '/old-contact': '/contact',
    }
    const dest = redirects[url.pathname]
    if (dest) return Response.redirect(url.origin + dest, 301)
  },
}

간단한 경로에서 경로로의 이동이 몇 개 있으면 대신 기본 제공 리다이렉트 엔진을 사용하십시오. 코드가 필요 없으며 설정에서 구성됩니다. 리다이렉트 및 재쓰기 구성을 참조하십시오.

보안 헤더 추가

export default async function handler(request) {
  const response = await fetch(request)
  const headers = new Headers(response.headers)
  headers.set('X-Frame-Options', 'DENY')
  headers.set('X-Content-Type-Options', 'nosniff')
  headers.set('Referrer-Policy', 'strict-origin-when-cross-origin')
  return new Response(response.body, {
    status: response.status,
    statusText: response.statusText,
    headers,
  })
}

정적 헤더 규칙의 경우 코드도 필요하지 않습니다. Settings에는 HSTS, CSP, no-embed, no-sniff, referrer policy 및 CORS에 대한 빠른 추가 사전 설정이 있는 응답 헤더 섹션이 있습니다.

A/B 라우팅

export default {
  async fetch(request) {
    const url     = new URL(request.url)
    const variant = Math.random() < 0.5 ? 'a' : 'b'
    url.searchParams.set('variant', variant)
    return fetch(url.toString(), request)
  },
}

환경 범위

범위실행 위치
All environmentsProduction, staging 및 모든 branch preview
Production onlyProduction 환경
Preview only모든 비프로덕션 환경

새 함수를 Preview only로 먼저 배포하고, branch preview에서 동작을 확인한 후, All environments로 전환합니다. Edge function은 모든 요청 앞에서 실행되므로 하나의 실수는 동시에 모든 페이지의 실수입니다.

여러 함수가 상호작용하는 방식

프로젝트의 활성화된 모든 함수는 생성된 순서대로 평가됩니다. 각 요청에 대해 엣지는 목록을 따라가며 경로 패턴이 요청 경로와 일치하고 범위가 환경을 포함하는 첫 번째 함수를 실행합니다.

  • 해당 함수가 Response를 반환하면 전송되고 평가가 중지됩니다.
  • 아무것도 반환하지 않으면 평가가 다음 일치하는 함수로 계속됩니다.
  • 이 중 어느 것도 Response를 반환하지 않으면 요청이 프로젝트로 정상 진행됩니다.

이는 초반에 생성된 넓은 /* 함수가 나중에 생성된 더 좁은 함수를 가릴 수 있음을 의미합니다. 넓은 함수가 Response를 반환하는 경우 말입니다. 구체적인 함수를 먼저 만들거나, 넓은 함수가 처리하지 않아야 하는 경로에 대해 아무것도 반환하지 않도록 만듭니다.

배포

Deploy to edge를 클릭합니다. 배포는 데이터베이스의 현재 상태에서 전체 엣지 네트워크의 단일 결합 라우터를 재생성하므로, 함수를 활성화, 비활성화, 편집 또는 삭제하면 모든 항목이 다시 게시됩니다. 변경사항은 일반적으로 몇 초 내에 적용됩니다.

각 함수 행은 마지막 배포의 단계를 표시하는 Deploy log와 성공하지 못한 경우 오류가 있는 DEPLOY FAILED 배지를 유지합니다.

Pause는 함수를 삭제하지 않고 라우터에서 제외하므로, 잘못된 함수를 빠르게 되돌리는 가장 빠른 방법입니다. Resume을 사용하여 다시 배치합니다.

함수에서 예외 발생

함수 내의 예외는 엣지에서 포착됩니다. 오류는 로깅되고 요청은 함수가 아무것도 반환하지 않은 것처럼 프로젝트로 전달됩니다.

이는 모니터링 시스템이 아니라 안전망입니다. 모든 요청에서 예외를 발생하는 함수는 방문자 관점에서 자동으로 실패하며, 트래픽은 함수가 존재하지 않는 것처럼 작동합니다. 함수가 의도된 효과를 멈춘 경우, 라우팅을 의심하기 전에 예외를 의심합니다.

제한

  • 프로젝트당 최대 20개 함수. 21번째는 거부됩니다.
  • 함수당 최대 64 KB 소스.
  • 이름은 최대 120자, 경로 패턴은 2048자입니다.

관련 읽기

여전히 도움이 필요하신가요?

다음 주소로 이메일을 보내주세요 support@kapsulehost.com 또는 KPanel에서 채팅을 시작하세요.

KPanel 열기