Nuxt는 ofetch를 사용하여 Vue 앱이나 API 라우트 내에서 HTTP 요청을 만들 수 있도록 $fetch 헬퍼를 전역적으로 노출합니다.
$fetch를 호출하면, 관련 함수를 직접 호출하여(요청을 에뮬레이션) 추가적인 API 호출을 절약합니다.$fetch를 useAsyncData로 감싸지 않고 사용하면, 데이터를 두 번 가져오게 됩니다. 처음에는 서버에서, 그다음에는 클라이언트 측 하이드레이션 중에 다시 가져오는데, 이는 $fetch가 서버에서 클라이언트로 상태를 전송하지 않기 때문입니다. 따라서 클라이언트가 데이터를 다시 가져와야 하므로, 양쪽에서 모두 fetch가 실행됩니다.컴포넌트 데이터를 가져올 때 이중 데이터 페칭을 방지하기 위해 useFetch 또는 useAsyncData + $fetch 사용을 권장합니다.
<script setup lang="ts">
// SSR 중에는 데이터가 서버에서 한 번, 클라이언트에서 한 번 총 두 번 가져와집니다.
const dataTwice = await $fetch('/api/item')
// SSR 중에는 데이터가 서버 측에서만 가져와지고 클라이언트로 전송됩니다.
const { data } = await useAsyncData('item', () => $fetch('/api/item'))
// useFetch를 useAsyncData + $fetch의 단축 형태로 사용할 수도 있습니다.
const { data } = await useFetch('/api/item')
</script>
클라이언트 측에서만 실행되는 메서드에서는 어디서든 $fetch를 사용할 수 있습니다.
<script setup lang="ts">
async function contactForm () {
await $fetch('/api/contact', {
method: 'POST',
body: { hello: 'world' },
})
}
</script>
<template>
<button @click="contactForm">
Contact
</button>
</template>
$fetch를 사용하는 경우, 환경 변수에 NODE_TLS_REJECT_UNAUTHORIZED=0을 설정해야 합니다.브라우저에서 $fetch를 호출할 때는 cookie와 같은 사용자 헤더가 API로 직접 전송됩니다.
그러나 서버 사이드 렌더링 중에는 서버 사이드 요청 위조(SSRF) 또는 인증 오용과 같은 보안 위험 때문에, $fetch는 사용자의 브라우저 쿠키를 포함하지 않으며, fetch 응답의 쿠키도 전달하지 않습니다.
<script setup lang="ts">
// 이는 SSR 중에 헤더나 쿠키를 전달하지 않습니다.
const { data } = await useAsyncData(() => $fetch('/api/cookies'))
</script>
export default defineEventHandler((event) => {
const foo = getCookie(event, 'foo')
// ... 쿠키로 무언가를 수행합니다.
})
서버에서 헤더와 쿠키를 전달해야 하는 경우, 수동으로 전달해야 합니다:
<script setup lang="ts">
// 이는 사용자의 헤더와 쿠키를 `/api/cookies`로 전달합니다.
const requestFetch = useRequestFetch()
const { data } = await useAsyncData(() => requestFetch('/api/cookies'))
</script>
그러나 서버에서 상대 URL로 useFetch를 호출할 때, Nuxt는 useRequestFetch를 사용하여 헤더와 쿠키를 프록시합니다 (host와 같이 전달되지 말아야 할 헤더는 예외입니다).