[Next] 三.next自定義服務(wù)器和路由

next 服務(wù)端渲染

實(shí)際上,next 一直都是執(zhí)行的服務(wù)端渲染.npm start執(zhí)行的是 next 自帶的服務(wù)器來運(yùn)行你的應(yīng)用.next 是支持自定義服務(wù)器的,同時(shí)能夠支持現(xiàn)有的路由和模式,你可以在此基礎(chǔ)上添加一些自己的需求.

新建/server.js

const express = require("express");
const next = require("next");
const dev = process.env.NODE_ENV !== "production"; //判斷是否開發(fā)環(huán)境
const app = next({ dev }); //創(chuàng)建一個(gè)next的app
const handle = app.getRequestHandler(); //請(qǐng)求處理

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

    //用來進(jìn)行簡(jiǎn)化路徑匹配
    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)創(chuàng)建而來

  • dev(bool)是否在開發(fā)模式下啟動(dòng) Next.js-默認(rèn) false
  • dir(string)項(xiàng)目所在的位置-默認(rèn)'.'
  • quiet(bool)隱藏包含服務(wù)器信息的錯(cuò)誤消息-默認(rèn) false
  • conf(object)與您要使用的對(duì)象相同 next.config.js-默認(rèn){}

同時(shí)修改 package.json 中的配置

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

解決使用路由隱藏 as 會(huì) 404 的問題

問題在這

例如

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

然后在npm run dev的情況下,我們使用 next 默認(rèn)的服務(wù)器.頁面在使用 as 的時(shí)候起了一個(gè)縮寫路徑名稱,這種情況在第一次進(jìn)入是正常匹配的,但是刷新就會(huì) 404,原因在于服務(wù)器目前并不清楚 b 代表的是什么路徑.

而在 server.js 中就添加了關(guān)于 b 的縮寫匹配

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

此時(shí)我們npm run server:dev開啟自定義服務(wù)器,打開頁面進(jìn)入縮寫路徑,我們刷新發(fā)現(xiàn)頁面會(huì)保留.

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

多路徑頁面

next 默認(rèn)會(huì)將 pages 下的 js 文件創(chuàng)建出對(duì)應(yīng)的路徑.我們起了路由別名,并且通過自定義路由讓路由的別名生效.但是我們?cè)俅屋斎?book/[currentBookId],發(fā)現(xiàn)依舊可以匹配到同樣的頁面,造成一個(gè)頁面擁有的 2 個(gè)及以上的路徑.這可能會(huì)導(dǎo)致 SEO 和 UX 問題

我們通過設(shè)置 useFileSystemPublicRoutes 來禁用默認(rèn)路由

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

重啟打開網(wǎng)站,book/[currentBookId]就會(huì)直接 404 了.

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

動(dòng)態(tài) assetPrefix

有時(shí)候我們需要?jiǎng)討B(tài)路由,比如根據(jù)基于請(qǐng)求更改 assetPrefix,這時(shí)候我們需要使用 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 到請(qǐng)求標(biāo)頭中。這個(gè)是由語言解析器或者應(yīng)用程序框架輸出的。這個(gè)值的意義用于告知網(wǎng)站是用何種語言或框架編寫的。

直接禁用它

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

Doc

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容