📜  Next.js 中的边缘函数和中间件

📅  最后修改于: 2022-05-13 01:56:41.224000             🧑  作者: Mango

Next.js 中的边缘函数和中间件

Next.js 是由 Vercel 开发的基于 React 的全栈框架,支持网页预渲染等功能。与将整个应用程序加载到客户端的传统反应应用程序不同。 Next.js 允许在服务器上呈现网页,这对性能和 SEO 来说非常有用。您可以在此处了解有关 Next.js 的更多信息。

Vercel 在最近对 Next.js 版本 12 的更新中引入了许多新功能,包括 Edge 功能和中间件。

直到最近,主要有两种向用户浏览器提供内容的方法:

  • 静态地从靠近用户位置的内容交付网络获得更快的响应时间,或者,

  • 对来自单个服务器的每个请求动态地使用不同的内容和逻辑。

这两种方法都有局限性,例如 CDN 无法缓存动态内容,服务器无法匹配 CDN 的交付速度。

什么是边缘函数?

Vercel 引入了 Edge 功能,以实现 CDN 的速度和服务器端的灵活性。边缘功能使开发人员能够在全球分布的服务器上运行他们的代码。这意味着您的代码将在用户更方便的位置执行。这允许开发人员将服务器端逻辑移动到边缘,更靠近访问者的来源,以加快响应时间。

如果您曾经使用过无服务器函数,那么上面的定义可能听起来很熟悉。

Edge 功能与无服务器功能有何不同?

  • 低延迟:我们部署在边缘的代码被复制到许多全球位置,因此它是从用户最近的地理位置执行的。来自世界各地的用户将体验到低延迟。
  • 无冷启动:当调用无服务器函数时,在执行前需要大约 250 毫秒的冷启动,但边缘函数提供 100 倍的启动时间,并将启动时间减少到几乎 0 毫秒。

使用 Edge 函数:在我们开始之前,您应该熟悉术语中间件。这不是一个新概念,但它最近才在 Next.js 中引入。中间件是在对 Next.js 发出每个请求之前执行的函数。所以,如果用户请求一个页面,中间件函数的逻辑首先被执行,然后是请求。 Vercel 引入的中间件将在边缘函数上执行。

示例:为了演示边缘功能的实际应用,我们将使用 Next.js 创建一个小型应用程序。我们将首先创建一个新的 Next.js 项目,然后使用 Next.js 中间件来实现受保护的路由。访问受保护的路由需要密钥;否则,用户将被重定向到主页。

第 1 步:运行以下命令创建一个新的 Next.js 应用程序(确保已安装 NPM 和节点):

npx create-next-app@latest myproject

当我们在代码编辑器中打开我们的项目时,我们会看到一个简单的项目结构。对于本教程的范围,我们将只关注 /pages 目录。我们将首先清理/pages/index.js文件。然后我们将创建一个名为protected的新路由。现在,在 pages 文件夹中创建一个名为/pages/_middleware.js的新文件。从此文件导出的任何函数都将被视为中间件并在边缘运行。我们的中间件逻辑将写在 _middleware.js 中。

项目结构:它将如下所示。

例子:

/pages/index.js
import React from 'react'
  
const Home = () => {
  return (
    

Home Page

  ) }    export default Home


/pages/protected.js
import React from 'react'
  
const Protected = () => {
  return (
    
Secret Data
  ) }    export default Protected


/pages/_middleware.js
import { NextResponse } from "next/server";
  
// This function will act as middleware
const middlewareHandler = (req) => {
  
  // We'll first check if route includes
  // the protected path
  if (req.url.includes("/protected")) {
  
    // Get the secret from the url params
    const urlParams = new URLSearchParams(req.nextUrl.search);
    const secret = urlParams.get("secret");
  
    // Check if secret exists, if it does
    // then it must be correct.
    if (secret && secret === "mysecret") {
  
      // If secret matches we will continue
      // to the protected route.
      return NextResponse.next();
  
    } else {
  
      // If the secret doesn't exist or is incorrect
      // we'll redirect to the index (Home) page.
      return NextResponse.redirect("http://localhost:3000/");
    }
  }
  
  // For all other routes, we won't change anything.
  NextResponse.next();
    
};
export default middlewareHandler;


/pages/protected.js

import React from 'react'
  
const Protected = () => {
  return (
    
Secret Data
  ) }    export default Protected

/pages/_middleware.js

import { NextResponse } from "next/server";
  
// This function will act as middleware
const middlewareHandler = (req) => {
  
  // We'll first check if route includes
  // the protected path
  if (req.url.includes("/protected")) {
  
    // Get the secret from the url params
    const urlParams = new URLSearchParams(req.nextUrl.search);
    const secret = urlParams.get("secret");
  
    // Check if secret exists, if it does
    // then it must be correct.
    if (secret && secret === "mysecret") {
  
      // If secret matches we will continue
      // to the protected route.
      return NextResponse.next();
  
    } else {
  
      // If the secret doesn't exist or is incorrect
      // we'll redirect to the index (Home) page.
      return NextResponse.redirect("http://localhost:3000/");
    }
  }
  
  // For all other routes, we won't change anything.
  NextResponse.next();
    
};
export default middlewareHandler;

运行应用程序:打开终端并输入以下命令。

npm run dev

输出: