學習 Next.js: 清潔URL的服務器支持

原始文檔在 https://github.com/developerw... 如今搬過來.node

學習 Next.js: 入門
學習 Next.js: 頁面之間的導航
學習 Next.js: 使用共享組件
學習 Next.js: 建立動態內容
學習 Next.js: 使用路由掩碼建立乾淨的URL
學習 Next.js: 乾淨URL的服務器支持
學習 Next.js: 獲取數據
學習 Next.js: 部署git

乾淨URL的服務器支持

在前面的課程中, 咱們學習瞭如何爲咱們的應用程序建立乾淨的URL. 基本上, 咱們讓URL像這樣:github

http://localhost:3000/p/my-blog-postshell

可是, 它如今只能用於客戶端導航. 當咱們從新加載頁面的時候, 它給了咱們一個404錯誤頁面.express

這是由於, 在pages目錄中, 並不存在一個實際的p/my-blog-post模塊文件.npm

404 Page

咱們使用Next.js的自定義服務器API來解決這個問題, 讓咱們看看如何使用它?json

設置

首先, 咱們需下載示例代碼:segmentfault

git clone https://github.com/arunoda/learnnextjs-demo.git
cd learnnextjs-demo
git checkout clean-urls

而後經過下面的命令運行咱們的示例程序:瀏覽器

npm install
npm run dev

最後經過 http://localhost:3000 訪問Web應用程序.服務器

建立自定義服務器

咱們使用 Express 來建立一個自定義服務器. 它很是簡單:

首先, 添加 Express 依賴到應用程序:

npm install --save express

而後建立一個 server.js 文件, 並添加下面的內容:

const express = require('express')
const next = require('next')

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

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

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

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

如今, 更新NPM的開發腳本爲:

{
  "scripts": {
    "dev": "node server.js"
  }
}

而後, 運行npm run dev, 你會看到什麼?

建立自定義路由

如今你所看到的, Next.js 能夠和 Express 一塊兒協同工做. 如今咱們要添加一個自定義的路由來匹配博客的URL.

用新的路由, server.js 看起來就是這個樣子:

const express = require('express')
const next = require('next')

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

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

  server.get('/p/:id', (req, res) => {
    const actualPage = '/post'
    const queryParams = { title: req.params.id }
    app.render(req, res, actualPage, queryParams)
  })

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

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

注意一下代碼塊:

server.get('/p/:id', (req, res) => {
    const actualPage = '/post'
    const queryParams = { title: req.params.id }
    app.render(req, res, actualPage, queryParams)
})

咱們簡單的映射了一個自定義路由到咱們現有的博客頁面 post. 同時咱們還映射了查詢串.

如今重啓應用程序, 訪問下面的地址:

http://localhost:3000/p/hello-nextjs

如今, 不會再顯示 404 頁面了, 由於, 經過自定義路由, 咱們把經過瀏覽器訪問的地址映射到了實際的頁面, 可是如今還有一個小問題, 你能看出來麼?

URL信息

咱們的 /post 頁面經過查詢串參數 title 來接收標題. 在客戶端路由中, 咱們能夠經過 Link 的 as 屬性設置正確的值.

<Link as={`/p/${props.id}`} href={`/post?title=${props.title}`}>
  <a>{props.title}</a>
</Link>

可是在服務器路由中, 咱們得不到這個title, 由於咱們只有一個URL中博客的ID, 所以咱們使用這個ID做爲服務器端查詢串參數.

你能夠經過以下的路由定義看到:

server.get('/p/:id', (req, res) => {
  const actualPage = '/post'
  const queryParams = { title: req.params.id }
  app.render(req, res, actualPage, queryParams)
})

這就是問題. 可是在實際應用中, 這實際上不是一個問題, 由於, 一般咱們在服務器端和客戶端都經過ID從數據服務器獲取數據. 所以實際上, 咱們只須要一個ID.

最後

如今咱們經過 Next.js 自定義服務器API 實現了一個簡單的應用程序. 以此爲基礎, 咱們添加了乾淨URL的服務器端支持. 就像這樣, 你能夠建立更多你想要的路由.

對於Web服務器, 不限於使用 Express 做爲服務器, 你能夠使用任何 Node.js Web框架. 對於 自定義服務器API的想信息文檔, 參考 定義服務器API文檔

相關文章
相關標籤/搜索