[Next] 三.next自定義服務器和路由


next 服務端渲染

實際上,next 一直都是執行的服務端渲染.npm start執行的是 next 自帶的服務器來運行你的應用.next 是支持自定義服務器的,同時能夠支持現有的路由和模式,你可以在此基礎上添加一些自己的需求.

新建/server.js

const express = require("express");
const next = require("next");
const dev = process.env.NODE_ENV !== "production"; //判斷是否開發環境
const app = next({ dev }); //創建一個next的app
const handle = app.getRequestHandler(); //請求處理

app
  .prepare()
  .then(() => {
    const server = express();

    //用來進行簡化路徑匹配
    server.get("/b/:currentBookId", (req, res) => {
      const actualPage = "/book/[currentBookId]";
      const queryParams = { currentBookId: req.params.currentBookId };
      app.render(req, res, actualPage, queryParams);
    });

    server.get("*", (req, res) => {
      return handle(req, res);
    });

    server.listen(6776, err => {
      if (err) throw err;
      console.log("> Ready on http://localhost:6776");
    });
  })
  .catch(ex => {
    console.error(ex.stack);
    process.exit(1);
  });

其中 app 有 next(opts: object)創建而來

  • dev(bool)是否在開發模式下啟動 Next.js-默認 false
  • dir(string)項目所在的位置-默認'.'
  • quiet(bool)隱藏包含服務器信息的錯誤消息-默認 false
  • conf(object)與您要使用的對象相同 next.config.js-默認{}

同時修改 package.json 中的配置

"server:dev": "node server.js",
"server:start": "NODE_ENV=production node server.js",

解決使用路由隱藏 as 會 404 的問題

問題在這

例如

<Link href={`/book/${item.id}`} as={`/b/${item.id}`}>

然后在npm run dev的情況下,我們使用 next 默認的服務器.頁面在使用 as 的時候起了一個縮寫路徑名稱,這種情況在第一次進入是正常匹配的,但是刷新就會 404,原因在於服務器目前並不清楚 b 代表的是什么路徑.

而在 server.js 中就添加了關於 b 的縮寫匹配

//用來進行簡化路徑匹配
server.get("/b/:currentBookId", (req, res) => {
  const actualPage = "/book/[currentBookId]";
  const queryParams = { currentBookId: req.params.currentBookId };
  app.render(req, res, actualPage, queryParams);
});

此時我們npm run server:dev開啟自定義服務器,打開頁面進入縮寫路徑,我們刷新發現頁面會保留.

之后npm run dev命令可以拋棄了

多路徑頁面

next 默認會將 pages 下的 js 文件創建出對應的路徑.我們起了路由別名,並且通過自定義路由讓路由的別名生效.但是我們再次輸入 book/[currentBookId],發現依舊可以匹配到同樣的頁面,造成一個頁面擁有的 2 個及以上的路徑.這可能會導致 SEO 和 UX 問題

我們通過設置 useFileSystemPublicRoutes 來禁用默認路由

// next.config.js
module.exports = {
  useFileSystemPublicRoutes: false,
}

重啟打開網站,book/[currentBookId]就會直接 404 了.

useFileSystemPublicRoutes 禁用來自 SSR 的文件名路由.客戶端路由仍然可以訪問這些路徑,需要攔截 popstate來配置客戶端也禁用.

動態 assetPrefix

有時候我們需要動態路由,比如根據基於請求更改 assetPrefix,這時候我們需要使用 app.setAssetPrefix

server.get("*", (req, res) => {
    if (req.headers.host === "my-app.com") {
    app.setAssetPrefix("http://cdn.com/myapp");
    } else {
    app.setAssetPrefix("");
    }
    return handle(req, res);
});

禁用 X-Powered-By

Next.js 將添加 x-powered-by 到請求標頭中。這個是由語言解析器或者應用程序框架輸出的。這個值的意義用於告知網站是用何種語言或框架編寫的。

直接禁用它

// next.config.js
module.exports = {
  poweredByHeader: false,
}

Doc


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM