如何從同一個源中提供React應用和後端應用,而無需在服務器上使用CORS並擔心端口的問題。

我認為最常用的啟動React應用的方式是使用create-react-app命令,這非常方便。

你可能會遇到的問題之一是如何將React應用與您已經擁有的後端應用程式或您可能想要創建的後端應用程式連接起來。

開發過程中

在開發應用程序時,您希望利用熱加載和其他便利的功能。那麼如何在不使用CORS並擔心端口的情況下將其與後端結合起來呢?

本文將以Express框架提供示例,但這個方法也適用於其他框架。

假設您正在進行測試,那麼讓我們創建一個React應用:

npx create-react-app testing

然後

cd testing

現在,在server.js文件中創建一個簡單的Express服務器,您可以將其添加到任何位置,甚至可以是一個單獨的文件夾。

如果您選擇將此文件添加到create-react-app應用程式代碼中,請運行:

npm install express

然後,添加以下簡單的Express設置:

const express = require('express');
const app = express();

app.get('/hey', (req, res) => res.send('ho!'))

app.listen(8080)

關鍵點:打開package.json文件,並將以下代碼添加到其中的某個位置:

"proxy": "http://localhost:8080"

這告訴React將API請求代理到使用Express構建的Node.js服務器。

現在使用node server.js運行此Node.js進程。在另一個窗口中,使用npm start啟動CRA應用。

當瀏覽器在端口3000上打開時(默認情況下),在DevTools中執行以下代碼:

fetch('/hey')

如果檢查網絡面板,您應該可以看到成功的響應以及ho!消息。

在生產環境中

在生產環境中,當您準備好部署時,您將運行npm run build來編譯React應用程序,並使用Express服務器來提供這些靜態文件。

整個代理的設置在生產環境中是無用的(它也無法正常工作,它只用於開發)。因此,如果您認為方便,可以將其保留在package.json文件中。

在以下代碼中,我們使用了path內置的Node模塊,並告訴應用程序提供React應用的靜態編譯版本:

const express = require('express')
const path = require('path')
const app = express()

app.use(express.static(path.join(__dirname, 'build')))

app.get('/ping', (req, res) => {
 return res.send('pong')
})

app.get('/', (req, res) => {
 res.sendFile(path.join(__dirname, 'build', 'index.html'))
})

app.listen(8080)