• 游客 您好:

    目前「IT人巴啦啦天地」需要數個專家協助發表文章。

    只要您願意,可以直接與我 ihstat 連絡。我將會給你「專家」身份。

    成為「專家」有什麼好處?目前暫時還沒有。我也只願意提供最多10名會員有這樣的身份。

    他可能可以成為未來非常高的權限。(除了管理) 也可以獲得由浩瀚星空站提供的資源。

  • 本站不接受任何被列入廣告發文黑名單的電子信箱。如您無法註冊,可能是您使用的電子信箱為廣告黑名單信箱。正常的信箱都是可以正常註冊。

    如果您可以証實您的信箱非廣告黑名單,請自行來信 hstaryoching#gmail.com 申請。

    申請請留下您的正統名稱及信箱,並告知從何得知及想進來的理由。

  • 浩瀚星空站已經重新整合並新增新的開發小站天地。

    採用新版的xenforo 2.2.3 做為最新的站點系統。

    中文搜尋已在本站啟用成功,歡迎多加測試看看

    有問題請再回報

教學 使用簡單的SSR伺服器 BY NODE

ihstar

管理員
管理成員
由於之前曾經有過一個專案需求。
客戶原本使用的是很單純的PHP+HTML的專案。
所以其使用者體驗很差。每一個換頁都會先白頁一下。(畢竟是請求的方式)

所以協助幫其使用了 VUE 元件的展示方式。
雖然使用者體驗變好了。但伴隨來的就是SEO不會讀取的問題。

於是,我用了AI及網路上的支援。簡單配合一下寫了一支臨時的SSR對應處理
先附上程式碼 index.js
JavaScript:
const express = require('express');
const { Cluster } = require('puppeteer-cluster');

const app = express();
const PORT = process.env.PORT || 3000;

(async () => {
  // 创建一个 Puppeteer Cluster
  const cluster = await Cluster.launch({
    concurrency: Cluster.CONCURRENCY_CONTEXT,
    maxConcurrency: 2, // 根据服务器性能调整此值
    puppeteerOptions: {
      headless: true,
      args: ['--no-sandbox', '--disable-setuid-sandbox']
    }
  });

  // 任务处理函数
  cluster.task(async ({ page, data: { url, acceptLanguage } }) => {
    await page.setExtraHTTPHeaders({ 'Accept-Language': acceptLanguage });
    await page.goto(url, { waitUntil: 'networkidle0' });
    return await page.content();
  });

  app.get('*', async (req, res) => {
    // 动态设置 Puppeteer 访问的 URL
    const protocol = req.headers['x-forwarded-proto'] || req.protocol;
    const host = req.headers['host'];
    const url = `${protocol}://${host}${req.originalUrl}`;
    const acceptLanguage = req.headers['accept-language'] || '';
    
    try {
      console.log(`Rendering URL: ${url} with Accept-Language: ${acceptLanguage}`);
      
      // 执行 Puppeteer Cluster 任务,传递 url 和 acceptLanguage
      const html = await cluster.execute({ url, acceptLanguage });
      res.send(html);
    } catch (error) {
      console.error('Error during SSR with Puppeteer:', error);
      res.status(500).send('An error occurred while rendering the page.');
    }
  });

  app.listen(PORT, () => {
    console.log(`SSR server is running on http://localhost:${PORT}`);
  });

  // 在进程终止时关闭集群
  process.on('SIGINT', async () => {
    await cluster.idle();
    await cluster.close();
    process.exit();
  });
})();

將上面的程式碼先放好一個位置。
再來就是開始準備工作了。

要用之前,要先準備好幾個事前工作
  1. 安裝無頭瀏覽器
    1. 豐富的(BB 代碼):
      wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.debsudo 
      apt install ./google-chrome-stable_current_amd64.deb
    2. 因為會需要用到它來處理頁面的回傳。
  2. 事前掛入好套件及建好環境
    1. 先進行初始化處理 yarn init -y
    2. 再來掛入套件 yarn add express puppeteer
以上都準備好後,就可以使用 node index.js 開始運行了。
如果需要背景運行,可以搭配 pm2 來處理。
不過一開始先確定一下是否運行成功。

不過這邊要先注意,由於這是後處理的方式。所以如果是直接應用到實際的專案上,會變得很慢。
所以我這裏還會搭配一些 WEB SERVER 。
只有 SEO 相關的連結進來才會跑SSR。(畢竟它慢沒關係)
這邊我就直接給 NGINX 的設定

先在 HTTP 區塊中給與如下設定
NGINX:
map $http_user_agent $proxy_pass_enabled {
    default 0;
    ~*(GTM|Googlebot|Bingbot) 1;
}
這是先給一個變數,用來判斷是否要觸發處理

再來就是到對應需要觸發的位置給判斷
NGINX:
location / {
    #這裏判斷要觸發SSR伺服器用,用剛剛給的變數判斷
     if ($proxy_pass_enabled) {
              proxy_pass http://localhost:3000;
     }
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    
    # 以下是原來的設定
    try_files $uri $uri/ /index.html;
}

以上很簡單的就是,利用了 user_agent 來判斷是否包含了(GTM|Googlebot|Bingbot) 這些值。
如果包含了就直接給與 proxy 到 http://localhost:3000

這邊的指向,你可在啟動SSR伺服器看到。只要跟它一樣就行。

這樣子處理是不是很方便呢?
當然啦。這只能簡單性的處理。如果碰上切頁等資料的。還是不會取到。
但至少是能應付大半問題了
 
頂部