---
title: "$fetch"
description: "Nuxt 使用 ofetch 全局暴露 $fetch 助手用于发起 HTTP 请求。"
canonical_url: "https://nuxt.zhcndoc.com/docs/3.x/api/utils/dollarfetch"
---
# $fetch

> Nuxt 使用 ofetch 全局暴露 $fetch 助手用于发起 HTTP 请求。

Nuxt 使用 [ofetch](https://github.com/unjs/ofetch) 全局暴露 `$fetch` 助手，用于在你的 Vue 应用或 API 路由内发起 HTTP 请求。

::tip{icon="i-lucide-rocket"}
在服务器端渲染期间，调用 `$fetch` 获取内部 [API 路由](https://nuxt.zhcndoc.com/docs/3.x/directory-structure/server) 时，会直接调用相关函数（模拟请求），**节省一次额外的 API 调用**。
::

::note{color="blue" icon="i-lucide-info"}
在组件中使用 `$fetch` 而不使用 [`useAsyncData`](https://nuxt.zhcndoc.com/docs/3.x/api/composables/use-async-data) 包装，会导致数据被请求两次：首次在服务器端，然后在客户端水合期间再次请求，因为 `$fetch` 不会将状态从服务器传递到客户端。因此，客户端必须重新获取数据，导致两端都会执行请求。
::

## 用法

我们建议使用 [`useFetch`](https://nuxt.zhcndoc.com/docs/3.x/api/composables/use-fetch) 或 [`useAsyncData`](https://nuxt.zhcndoc.com/docs/3.x/api/composables/use-async-data) + `$fetch`，以避免在获取组件数据时重复请求数据。

```vue [app.vue]
<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>
```

::read-more{to="https://nuxt.zhcndoc.com/docs/3.x/getting-started/data-fetching"}
::

你可以在只在客户端执行的方法中使用 `$fetch`。

```vue [pages/contact.vue]
<script setup lang="ts">
async function contactForm () {
  await $fetch('/api/contact', {
    method: 'POST',
    body: { hello: 'world' },
  })
}
</script>

<template>
  <button @click="contactForm">联系</button>
</template>
```

::tip
在 Nuxt 中，推荐使用 `$fetch` 发起 HTTP 请求，而非为 Nuxt 2 设计的 [@nuxt/http](https://github.com/nuxt/http) 和 [@nuxtjs/axios](https://github.com/nuxt-community/axios-module)。
::

::note
如果你在开发环境中使用 `$fetch` 调用带有自签名证书的（外部）HTTPS URL，需要在环境变量中设置 `NODE_TLS_REJECT_UNAUTHORIZED=0`。
::

### 传递 Headers 和 Cookies

当我们在浏览器中调用 `$fetch` 时，用户的 headers（如 `cookie`）会被直接发送给 API。

但是，在服务器端渲染期间，出于安全风险考虑，如 **服务器端请求伪造（SSRF）** 或 **认证误用**，`$fetch` 不会包含用户浏览器的 cookie，也不会传递 fetch 响应中的 cookie。

::code-group
```vue [pages/index.vue]
<script setup lang="ts">
// SSR 期间不会转发 headers 或 cookies
const { data } = await useAsyncData(() => $fetch('/api/cookies'))
</script>
```

```ts [server/api/cookies.ts]
export default defineEventHandler((event) => {
  const foo = getCookie(event, 'foo')
  // ... 对 cookie 进行处理
})
```
::

如果你需要在服务器端转发 headers 和 cookies，必须手动传递它们：

```vue [pages/index.vue]
<script setup lang="ts">
// 这会将用户的 headers 和 cookies 转发给 `/api/cookies`
const requestFetch = useRequestFetch()
const { data } = await useAsyncData(() => requestFetch('/api/cookies'))
</script>
```

但是，在服务器上使用相对 URL 调用 `useFetch` 时，Nuxt 会使用 [`useRequestFetch`](https://nuxt.zhcndoc.com/docs/3.x/api/composables/use-request-fetch) 代理 headers 和 cookies（但不会转发不应转发的 headers，例如 `host`）。

---

- [源码](https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/entry.ts)


## Sitemap

See the full [sitemap](https://nuxt.zhcndoc.com/sitemap.md) for all pages.
