Categories: Next.js教程

Next.js教程:路由 API中间件

先看下实例:

API 路由提供了内置的中间件,用于解析传入的请求 (req)。这些中间件是:

  • req.cookies-包含请求发送的Cookie的对象。默认为{}
  • req.query-包含查询字符串的对象。默认为{}
  • req.body-包含由解析的主体的对象content-type,或者null如果未发送任何主体,则为

自定义配置

每个 API 路由都可以导出(export)一个用以更改默认配置 config 对象,如下所示:

export const config = {
  api: {
    bodyParser: {
      sizeLimit: '1mb',
    },
  },
}

该 api 对象包括可用于 API 路由的所有配置。

bodyParser 用于正文解析,如果你希望以 Stream 形式接收数据,可将将其禁用,如下所示:

export const config = {
  api: {
    bodyParser: false,
  },
}

bodyParser.sizeLimit 代表的是可以解析的数据负载的的最大体积,可以采用 bytes 所支持的任何格式,例如:

export const config = {
  api: {
    bodyParser: {
      sizeLimit: '500kb',
    },
  },
}

externalResolver 是一个显式标志,用以告诉服务器此路由正在由外部解析器(例如 express 或 connect)处理。启用此参数将禁用针对未处理的 request(请求)所发出的警告。

export const config = {
  api: {
    externalResolver: true,
  },
}

针对 Connect/Express 中间件的支持

你还可以使用 Connect 兼容的中间件。

例如,可以利用 cors 软件包为 API 端点 配置 CORS 。

首先来安装 cors

npm i cors
# or
yarn add cors

现在,将 cors 添加到 API 路由中:

import Cors from 'cors'

// Initializing the cors middleware
const cors = Cors({
  methods: ['GET', 'HEAD'],
})

// Helper method to wait for a middleware to execute before continuing
// And to throw an error when an error happens in a middleware
function runMiddleware(req, res, fn) {
  return new Promise((resolve, reject) => {
    fn(req, res, (result) => {
      if (result instanceof Error) {
        return reject(result)
      }

      return resolve(result)
    })
  })
}

async function handler(req, res) {
  // Run the middleware
  await runMiddleware(req, res, cors)

  // Rest of the API logic
  res.json({ message: 'Hello Everyone!' })
}

export default handler

进入 支持 CORS 的 API 路由 示例以查看完整的应用程序代码

使用TypeScript扩展req/res对象

为了获得更好的类型安全性,不建议扩展reqres对象。而是使用纯函数与它们一起使用:

// utils/cookies.ts

import { serialize, CookieSerializeOptions } from 'cookie'
import { NextApiResponse } from 'next'

/**
 * This sets `cookie` using the `res` object
 */
export const setCookie = (
  res: NextApiResponse,
  name: string,
  value: unknown,
  options: CookieSerializeOptions = {}
) => {
  const stringValue =
    typeof value === 'object' ? 'j:' + JSON.stringify(value) : String(value)

  if ('maxAge' in options) {
    options.expires = new Date(Date.now() + options.maxAge)
    options.maxAge /= 1000
  }

  res.setHeader('Set-Cookie', serialize(name, String(stringValue), options))
}

// pages/api/cookies.ts

import { NextApiRequest, NextApiResponse } from 'next'
import { setCookie } from '../../utils/cookies'

const handler = (req: NextApiRequest, res: NextApiResponse) => {
  // Calling our pure function using the `res` object, it will add the `set-cookie` header
  setCookie(res, 'Next.js', 'api-middleware!')
  // Return the `set-cookie` header so we can display it in the browser and show that it works!
  res.end(res.getHeader('Set-Cookie'))
}

export default handler

如果无法避免扩展这些对象,则必须创建自己的类型以包括额外的属性:

// pages/api/foo.ts

import { NextApiRequest, NextApiResponse } from 'next'
import { withFoo } from 'external-lib-foo'

type NextApiRequestWithFoo = NextApiRequest & {
  foo: (bar: string) => void
}

const handler = (req: NextApiRequestWithFoo, res: NextApiResponse) => {
  req.foo('bar') // we can now use `req.foo` without type errors
  res.end('ok')
}

export default withFoo(handler)

请记住,这是不安全的,因为即使您withFoo()从导出中删除代码,代码仍会编译。

terry

这个人很懒,什么都没有留下~

Share
Published by
terry

Recent Posts

vue:页面注入js修改input值

一般会直接这样写: let z…

19 小时 ago

聊聊vue3中的defineProps

在Vue 3中,defineP…

2 周 ago

在 Chrome 中删除、允许和管理 Cookie

您可以选择删除现有 Cooki…

2 周 ago

自定义指令:聊聊vue中的自定义指令应用法则

今天我们来聊聊vue中的自定义…

3 周 ago

聊聊Vue中@click.stop和@click.prevent

一起来学下聊聊Vue中@cli…

4 周 ago

Nginx 基本操作:启动、停止、重启命令。

我们来学习Nginx基础操作:…

1 月 ago