昨天,我们有NextJS Conf,我们得到了很多新东西。NextJS 12已经发布,它拥有大量令人兴奋的新功能。其中一个特性是 NextJS 中的中间件让我们通过一个示例来看看它是如何工作的。

NextJS中间件是什么?

中间件是一段简单的代码,它允许人们在请求完成之前修改对请求的响应。我们可以根据用户的请求重写、重定向、添加标题甚至流式传输 HTML。

这个定义来自NextJS Middleware Docs

NextJS 12 入门

对于这个例子,我将在Replit中做所有事情。您也可以跟我一起学习本教程。

Repl -replit.com/@AnishDe12020/NextJS-12-Middleware

使用create-next-app创建 NextJS 项目将为我们提供一个设置 NextJS 11 的项目(截至 2021 年 10 月 27 日),因此,首先,我们需要升级到 NextJS 12。

使用 NPM -

npm install next@latest

用纱线 -

yarn add next@latest

一个简单的中间件

现在,要添加中间件,我们需要在 pages 目录中创建一个_middleware.js文件。请注意,您也可以在 pages 目录的子目录中添加中间件文件,使其在顶级中间件文件之后运行。更多信息可以参考NextJS中间件执行顺序文档。

现在让我们编写一个简单的中间件函数 -

const middleware = (req, ev) => {
  return new Response(req.ua.os.name);
};

export default middleware;

这将在页面上显示用户的操作系统。我们将 HTML 流式传输给用户,但现在让我们看看如何在底层重写路由。

底层重写路由的中间件

首先,我们将创建一个名为[os].js的新文件并将index.js代码复制到其中,只需替换函数名称即可。

[os].js-

import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'

export default function Home() {
  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1 className={styles.title}>
          Welcome to <a href="https://nextjs.org">Next.js!</a>
        </h1>
      </main>

      <footer className={styles.footer}>
        <a
          href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
          target="_blank"
          rel="noopener noreferrer"
        >
          Powered by Vercel
            and Replit
        </a>
      </footer>
    </div>
  )
}

现在让我们回到我们的_middleware.js文件并进行一些更改。首先我们将导入NextResponse

import {NextResponse} from "next/server"

现在,让我们将用户的操作系统存储在一个变量中

const os = req.ua.os.name

现在,我们可以将 URL 重写为我们创建的新路由,这就是NextResponse的用武之地。

return NextResponse.rewrite(`/${os}`) // This return is necessary

这就是_middleware.js文件现在应该看起来的样子 -

import {NextResponse} from "next/server"

const middleware =  (req, ev) => {
  const os = req.ua.os.name

  return NextResponse.rewrite(`/${os}`)
};

export default middleware;

现在让我们在新路由中导入 Next Router

import {useRouter} from "next/router"

由于这是一个反应钩子,我们需要在返回的函数内部创建一个 NextJS 路由器的新实例。

const router = useRouter()

我们可以从前面在中间件中重写的 URL 参数获取用户的操作系统

const os = router.query.os

最后,让我们向用户展示他们正在使用的操作系统

<h1 className={styles.title}>
      You are using the {os} operating system
</h1>

最后这就是[os].js应该是什么样子 -

import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'
import {useRouter} from "next/router"

export default function Os() {
  const router = useRouter()

  const os = router.query.os
  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1 className={styles.title}>
          You are using the {os} operating system
        </h1>
      </main>

      <footer className={styles.footer}>
        <a
          href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
          target="_blank"
          rel="noopener noreferrer"
        >
          Powered by Vercel
            and Replit
        </a>
      </footer>
    </div>
  )
}

现在如果我们访问主页,我们应该会看到这个(注意我已经删除了一些 nextjs 样板代码) -

image.png

我可以使用浏览器开发工具模拟浏览器用户代理,我们得到操作系统的不同结果 -

image.png

现在,请注意 URL 是https://nextjs-12-middleware.anishde12020.repl.co/而不是https://nextjs-12-middleware.anishde12020.repl.co/Linuxhttps://nextjs-12-middleware.anishde12020.repl.co/Mac Os。这是因为,我们在中间件中重写了请求,因此客户端没有任何变化。

NextJS 中间件在后台是如何工作的?

NextJS 中间件使用Vercel 的边缘函数运行在V8 引擎上。 V8 引擎是一个用 C++ 编写的 JavaScript 引擎,由 Google 维护。它比在虚拟机或容器上运行 NodeJS 快得多,而且 Vercel 声称这些边缘功能是即时的。

边缘函数的局限性

一些 NodeJS API 不适用于中间件(因为它们是边缘函数),例如文件系统 API。此外,某些 NodeJS 模块将无法工作,因为仅允许使用已实现 ES 模块且不使用任何本机 NodeJS API 的模块。有关更多信息,请参阅此处的

收尾

到目前为止,我们已经看到了中间件的强大功能以及它将如何成为开发人员的一个巨大功能。通过使用中间件,可以快速轻松地完成服务本地化网站、提供基于区域的折扣、身份验证、机器人检测等等的事情。

Vercel 的团队还整理了许多使用中间件的示例。在这里查看

这就是这篇文章的内容,请随时在下面留下评论,您也可以在Twitter上与我联系

Logo

ModelScope旨在打造下一代开源的模型即服务共享平台,为泛AI开发者提供灵活、易用、低成本的一站式模型服务产品,让模型应用更简单!

更多推荐