【问题标题】:Manifest does not load when redirecting with middleware Next JS使用中间件 Next JS 重定向时不加载清单
【发布时间】:2022-06-14 04:40:58
【问题描述】:

我已经用 Next JS 做了几个 pwa 项目,但是这次我的 site.webmanifest 文件没有加载。当我在浏览器中查看 site.webmanifest 时,我看到它加载了一个带有起始页面的 html 文件。

site.webmanifest:

{
  "name": "Task Manager",
  "short_name": "Task Manager",
  "description": "Application to save tasks",
  "display": "standalone",
  "start_url": "/",
  "icons": [
    {
      "src": "/icons/manifest-icon-192.maskable.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "any"
    },
    {
      "src": "/icons/manifest-icon-192.maskable.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "maskable"
    },
    {
      "src": "/icons/manifest-icon-512.maskable.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any"
    },
    {
      "src": "/icons/manifest-icon-512.maskable.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "maskable"
    }
  ]
}

_middleware.tsx:

import { NextFetchEvent, NextRequest, NextResponse } from "next/server";

export function middleware(req: NextRequest, event: NextFetchEvent) {
  const jwt = req.cookies["jwt"];
  const urlArray: Array<string> = req.url.split("/");
  const baseUrl = `${urlArray[0]}//${urlArray[2]}`;
  if (req.url !== `${baseUrl}/login` && !jwt) {
    return NextResponse.redirect(`${baseUrl}/login`);
  }
}

链接到 _document.tsx 中的清单

<link rel="manifest" href="/site.webmanifest" />

错误:Error on browser console

编辑:我发现发生此错误是因为我在未经身份验证时使用中间件重定向到登录页面。但是我仍然没有解决这个问题,因为我想保留中间件。

【问题讨论】:

  • 您的 Next.js 应用中是否有任何重定向设置?
  • 你在哪里有 site.webmanifest 文件?
  • @juliomalves 我发现错误的原因是因为我在未经身份验证时使用中间件重定向到登录页面。您知道如何在保持中间件不变的同时修复此错误吗?

标签: next.js progressive-web-apps manifest.json


【解决方案1】:

找到了可能的问题,我也遇到了同样的问题。

pages/_middleware.ts 中的 Next.js 中间件拦截所有发出的请求,甚至是对“public/images”或在您的情况下是 /site.webmanifest 发出的请求

你的中间件告诉任何请求都需要有一个 jwt 或者是 /login,所以这个中间件阻止了对 /site.webmanifest 的请求

还是不知道是不是Nextjs的意图

if ((req.url !== `${baseUrl}/login` || req.url !== '/site.webmanifest') && !jwt) {
    return NextResponse.redirect(`${baseUrl}/login`);
}

添加诸如私有路由之类的内容,以便中间件仅阻止对它们的请求

const privatePaths = [/\/privateRoute2/,/\/privateRoute1\/*/]
const isPrivate = privatePaths.some(rx => rx.test(req.nextUrl.pathname));
if (isPrivate && !jwt) {
    const url = req.nextUrl.clone()
    url.pathname = '/authenticate'
    return NextResponse.redirect(url, 302);
}
return NextResponse.next()

【讨论】:

    【解决方案2】:

    很好的答案@Santiago,

    没错,nextjs middleware 是新的,目前是测试版。它基本上拦截了您的所有路由,包括从 pubic/ 文件夹提供的资产文件。解决此问题的最简单方法是实际确保排除带有扩展名的文件(即 .png、.jpg、.manifest、.json 等)

    const PUBLIC_FILE = /\.(.*)$/;
    const isPublicFiles = PUBLIC_FILE.test(req.nextUrl.pathname);
    if (!jwt && !isPublicFiles) {
      const token = await auth.currentUser?.getIdToken();
      const url = req.nextUrl.clone();
      url.pathname = '/login';
    
      return NextResponse.redirect(url);
    }
    return NextResponse.next();
    

    【讨论】:

      猜你喜欢
      • 2021-07-22
      • 1970-01-01
      • 2021-09-03
      • 2021-01-23
      • 1970-01-01
      • 1970-01-01
      • 2017-12-22
      • 2022-12-14
      • 2023-02-13
      相关资源
      最近更新 更多