簡體   English   中英

NodeJS 或 ReactJs 中的域和子域路由

[英]Domain and subdomain routing in NodeJS or ReactJs

web頁面的總體思路:

  1. domain.com:指向管理員和賣家的登錄頁面。
  2. shop.domain.com:指向賣家的店鋪。
  3. 計划使用 React.js 作為前端,使用 Nodejs (Express Js) 作為后端。
  4. 尚未決定在 Heroku 上托管所有內容,或者僅在 Heroku 和 React.js 上托管 Nodejs 后端,因為我們正在分離開發過程。

如何根據 URL 訪問(帶或不帶子域)將用戶重定向到相應頁面

事實上,npm 中有一個名為express-subdomain-handler的 package,它可以幫助服務器端的域和子域路由,我沒有問題完成並部署到 Z1A79417461C9AD3988F8B93E

app.use(subdomainHandler({
    baseUrl: 'localhost',
    prefix: 'subdomain',
    logger: true
}));

app.get('/', function (request, response) {
    response.send('WELCOME TO LOCALHOST');
});

app.get('/subdomain/:shop', function (request, response) {
    response.send('WELCOME TO SUBDOMAIN');
});

我相信上面的路由更傾向於服務器端渲染,因為它只根據訪問的 URL(或端點)渲染相應的頁面。 但是可以通過這種方式渲染 React 應用程序嗎? 因為我之前所做的基本上只是渲染.ejs頁面,這就是為什么我對此不確定,而且我之前從未使用過 React.js。

Secondly, What if I host the React app on another server, maybe Vercel or NGINX or anything, and access the backend service in heroku by using REST API, is this a correct method to deploy a website? 如果是這樣,域和子域路由是在 React 應用程序的托管站點還是在代碼本身內部完成,而不是 Heroku 中的 expressjs? 因為我相信 expressjs 只負責創建一系列端點來監聽。 例如,在 express.js 中:

app.get('/hello', (req, res) => {
   res.send("Hello from domain");
})

app.get('/subdomain/hello', (req, res) => {
   res.send("Hello from subdomain");
})

而react app只需要訪問這些API即可,無需考慮后端子域和域的路由問題。 我相信這在某種程度上被稱為客戶端渲染,因為每個 REST API 將返回 JSON 數據進行渲染。

那么如果我這樣執行,我們如何根據訪問的URL來確定React app要顯示的頁面呢? 例如,如果domain.com將引導至儀表板頁面,而shop.domain.com將引導至商店頁面?

首先,我從未使用過 Heroku 進行托管,因此我的解決方案可能會因您的環境而異,但我認為整個概念都適合您。

您的問題沒有固定答案,但我現在的想法可能對您有所幫助:) 您的問題有很多子問題,所以我將其分開。

而且我的英語不流利,因此您和我之間可能存在一些誤解,如果我從您的問題中理解的內容有誤,請告訴我。

Q. 但是可以通過這種方式渲染 React 應用程序嗎?

(我的理解是:react app 可以由 SSR 托管)

A. 您可以使用代碼拆分和服務器端渲染為帶有 SSR 的 React 應用程序提供服務,除非您需要完整的 SSR 應用程序,否則您最好對一些元標記和 SEO 需要的頁面使用服務器端渲染。 如果您需要完整的 ssr,也有一些花哨的框架,Next.js。 參考 Vercel,您可能已經知道這一點。

Q. What if I host the React app on another server, maybe Vercel or NGINX or anything, and access the backend service in heroku by using REST API

(我的理解是:react app 可以托管在另一台服務器上嗎?NGINX = 使用服務器實例,Vercel:使用無服務器架構)

A. 也可以這樣托管。 似乎這個更像反應。 但我不推薦使用 Vercel 進行托管,因為電子商務服務需要很多端點,請查看 Vercel 的定價政策。

問:假設我正在使用 Heroku 作為 Express 后端,這是否意味着我需要分別創建 2 個應用程序而不是將它們組合在一起

A. 您可以為計算機資源托管多個主機,也可以不托管。 如果您計划多主機,您可能需要代理服務器指向其他服務器,相反,對於單主機,反向代理指向每個應用程序。

Q. express-subdomain-handler vs. vhost

A. 沒有固定的答案。 你可以使用 vhost 或 express-subdomain-handler 來實現你想要的。 或兩者。

我的解決方案概念是使用帶有反向代理的單個服務器實例。 讓 Nginx 虛擬將您的多個應用程序托管在單個服務器中。

我推薦的:

應用列表。

  1. 反應主機 - nodejs應用程序
  2. 客戶端 api 主機 - nodejs 應用程序
  3. 管理員反應主機 - nodejs應用程序
  4. 客戶端 api 主機 - nodejs 應用程序

我使用 AWS S3 托管 React 應用程序,使用 EC2 托管 API 應用程序。

結構概念。

( NS / DNS ) : domain.com points your-ip
    |
    ( Server instance )
        |
        ( Nginx ) - virtual hosting
            |
            ( www.domain.com ) --- > client react host : ( node app for server side rendering ) : React rendered file for each route. 
                                                       Or you can just respond with index.html for all route for skipping SSR
            |
            ( api.domain.com ) --- > clinet api host : api.domain.com/what, api.domain.com/what/ever?you=want
            |
            ( admin.domain.com ) ---> admin react host : admin.domain.com/* : sending index.html  //static hosting and let all route point for index.html
            |
            ( admin-api.domain.com ) ---> admin react host : Only if you want to seperate. Or you can combine this with api.domain.com using subrouter

如何構建結構。

步驟 1. 服務器托管。

I don't know much about Heroku but I guess there are aws ec2-like service(cloud computing) and s3-like service(static file service),
This can be single or multiple depending your choice. let's say you wanna go with single server and use virtual host for multiple service end point.

Step 2. 網絡層設置

let's say name-server and DNS server part is network layer. I used AWS Route 53 for this.

    2.1 Buy an domain
    www.your-service.com 
    
    2.2 Add some CNAME to point your web-server host
    - your-service.com,
    - www.your-service.com
    - api.your-service.com,
    - admin.your-service.com    
.
.
.

Step 3.創建nodejs應用(應用層)

I'm assuming that you had one already judging by code in your question.

ubuntu@ip-your-ip:~/project$ ls
api  cli   admin   admin-api   config   libraries  middlewares  models  node_modules   package.json 

ubuntu@ip-your-ip:~/project$ cd api

ubuntu@ip-your-ip:~/project/api$ ls
README.md  app.js  bin  config.json  pm2.config.js  node_modules  package.json  routes

ubuntu@ip-your-ip:~/project/api$ pm2 start pm2.config

PM2 是節點應用程序 deamonizer,您可以為此使用任何守護程序。

PM2 參考。 https://pm2.keymetrics.io/docs/usage/application-declaration/

步驟 3. nodejs 應用程序的 Nginx 點


nano /etc/nginx/nginx.conf

listen 80;
server_name client.domain.com;
location / {
             proxy_http_version 1.1;
             proxy_pass  http://localhost:3000;
}

listen 80;
server_name api.domain.com;
location / {
             proxy_http_version 1.1;
             proxy_pass  http://localhost:3001;
}

listen 80;
server_name admin.domain.com;
location / {
             proxy_http_version 1.1;
             proxy_pass  http://localhost:4000;
}

listen 80;
server_name admin-api.domain.com;
location / {
             proxy_http_version 1.1;
             proxy_pass  http://localhost:4001;
}

我希望這個解決方案對你有幫助:)

1.關於子域

api/ 和 api/subdomain 可以由 NGINX 虛擬主機實現,但是由於您計划為子域進行虛擬托管,因此 api.domain.com。

go 與 api.domain.com/foo,sub.domain.com/bar 似乎更合理!

前任。

listen 80;
server_name api.domain.com/api;
location / {
             proxy_http_version 1.1;
             proxy_pass  http://localhost:4000;
}

listen 80;
server_name api.domain.com/api/subdomain;
location / {
             proxy_http_version 1.1;
             proxy_pass  http://localhost:4000;
             #notice that api application is one and you are seperating namespace in it.
             #you can do the same thing in Node.js with subrouter. ( check out Router API in Nodejs official Site )
}
api.domain.com/foo, sub.domain.com/bar
listen 80;
server_name api.domain.com;
location / {
             proxy_http_version 1.1;
             proxy_pass  http://localhost:4000;#this one is node application listening port 4000
}

listen 80;
server_name sub.domain.com/;
location / {
             proxy_http_version 1.1;
             proxy_pass  http://localhost:4001;#and this is node application listening port 4001
}

在第一種情況下訪問。


    GET    api.domain.com/api/foo
    GET    api.domain.com/api/subdomain/bar

在第二種情況下訪問。


    GET    api.domain.com/foo
    GET    sub.domatin.com/bar


2. 如此真實。 讓每個 CNAME 指向您的 EC2(或任何服務器實例上的任何 web 應用程序)作為來源


3. 您不需要為您的 S3 實例配置服務器引擎。

S3 不在 EC2 實例中,而是在 AWS 數據中心的某個地方。 所以虛擬主機不是路由 S3 存儲桶的解決方案。 您可以使用 Route53 為您的域路由 S3 存儲桶,而不是這樣做。

如果您已經有一個域。 您可以將名稱服務器配置為指向 AWS 名稱服務器。 注冊域后,您可以從 Route 53 控制台獲取 NS/DNS。

同時,static 托管 react 應用程序(類似 S3 的托管)存在問題,您必須放棄 SSR。 因為 S3 是 static 主機,它不能像 Lambda 或服務器實例那樣執行。

S3 將只檢索請求的存儲文件,在這種情況下,它將是 react 應用程序的構建文件。 因此,如果我是您,我將使用 S3 的 go 僅用於管理員反應應用程序,因為 SEO 在管理員應用程序中並不重要。

用 express 做 SSR

讓您的根域( www.domain.com )指向 EC2 中的客戶端 nodejs 服務器。 並嵌套服務器的反應構建文件。 通過 Express 的 React SSR 應用程序解釋起來非常復雜,但是有很多例子,所以你可能想用谷歌搜索一下。


題外話,我在 S3 上構建了我的電子商務反應應用程序,我很遺憾這樣做,因為 SSR 部分並不容易。 有很多關於它的解決方案,但其中,next.js 框架似乎是盡快做 ssr 的最佳選擇。

我認為這不是反應部分。 React 是瀏覽器庫,無法處理域部分。

我也不建議用 express 處理這部分,因為這需要使用反向代理,你最好使用 Nginx,Apache,其他一些服務器引擎來處理子域。

你計划的可以這樣托管,

領域

  1. 創建域.com
  2. 將 cname 添加到 shopping.domain.com

服務器

  1. 創建管理服務器,客戶端服務器
  2. 反向代理那些服務器

客戶

  1. 創建 2 個反應項目。
  2. domain.com 服務於管理員反應構建文件。
  3. shop.domain.com 服務商店反應構建文件。

如果您不需要為搜索引擎公開管理頁面,我還建議為管理員反應應用程序托管 static 文件托管。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM