【问题标题】:Connecting Front-end React to Back-end Nodejs, both hosted on different origins将前端 React 连接到后端 Nodejs,两者都托管在不同的来源
【发布时间】:2020-09-22 14:46:13
【问题描述】:

我有一个非常有趣的问题来找你,在网上搜索了整整两天后,我想我会来找你的。

我有一个托管在 cPanel 上的前端 React 应用程序,它运行良好。然后我在 Node + Express 中为它构建了我的后端,作为一个单独的项目,我将它部署在 DigitalOcean 上。我为后端使用 digitalocean 的原因是因为我的 cPanel 服务器不允许我进行 ssh 访问,而且他们的支持无法访问,所以我不得不选择不同的选项。

API 也是实时的,我为我的 droplet 选择了与我的 React 应用程序相同的域,比如说 example.com。 这是一个 RESTful API,所以路由是 /api/v1/...

现在,当我尝试击中我的一条路线时,即。 example.com/api/v1/gallery,我得到一个 html 文档作为响应:

<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <link rel="icon" href="/logo-icon.png" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <link rel="apple-touch-icon" href="/logo-icon.png" />
    <link rel="manifest" href="/manifest.json" />
    <title>example</title>
    <link href="/static/css/main.58efad5e.chunk.css" rel="stylesheet">
</head>

<body><noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <script>
        !function(e){function r(r){for(var n,l,i=r[0],f=r[1],a=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,a||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var f=t[i];0!==o[f]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this.webpackJsonpedelweiss=this.webpackJsonpedelweiss||[],f=i.push.bind(i);i.push=r,i=i.slice();for(var a=0;a<i.length;a++)r(i[a]);var p=f;t()}([])
    </script>
    <script src="/static/js/2.345244fe.chunk.js"></script>
    <script src="/static/js/main.814906bd.chunk.js"></script>
</body>

</html>

所以我的问题是,这甚至可能吗?如果是这样,我该怎么做才能解决它? 我认为我的 api 和前端设置正确,但如果您需要更多信息,请告诉我,以便我可以分享。

我的目标是将我的前端 React 应用程序 (example.com) 托管在 cPanel 上,并将我的 Nodejs API 托管在同一域 (example.com) 上的 digitalocean 上,我可以点击路由 example.com/api/v1/gallery .

希望大家帮帮我。

【问题讨论】:

    标签: node.js reactjs hosting cpanel digital-ocean


    【解决方案1】:

    正如 Venkat 上面所说,您可以将 React App 和 Node 后端放在不同的源上,而不是在您设置的同一个 digitalocean droplet 上。

    为此,您需要为您的 react 应用程序的构建包提供服务,并且您可以使用 express 将您的前端作为静态文件提供服务。这在create-react-app 文档here 中有很好的记录

    我已经构建了一个 web 应用程序 (reference),它遵循使用 express 为 react 应用程序提供服务的相同方法,示例代码如下,

    const express = require("express");
    const app = express();
    
    // build is the folder which has my bundled react app
    // generate this using 'npm run build' if you are using 'cra'
    
    app.use(express.static(path.join(__dirname, "build")));
    
    // this will serve the index.html file when you open your domain `example.com`
    
    app.get("/*", (req, res) => {
      res.sendFile(path.join(__dirname, "build", "index.html"));
    });
    
    // you can specify your API routes here as you normally do
    

    这将让您将前端和后端托管在同一主机上。

    【讨论】:

    • 是的,我知道该怎么做,但是我的域已经使用 cPanel 在某个托管服务提供商处注册。你是说如果我从那个 cPanel 中删除我的项目,并像这样在我的数字海洋水滴上托管它,它会按预期工作吗?而且我将不得不取消我的 cPanel 托管,只为数字海洋托管付费,对吗?
    • 没错。我相信您必须在域提供商控制台中进行一些更改以更新名称服务器条目,以便您的域仅指向您的 digitalocean droplet
    【解决方案2】:

    @Peter Kartalov,是的,我们绝对可以做到这一点。这个问题的解决方案之一是我们可以从 node/express 应用程序中提供 react 应用程序,而不是在 cPanel 上托管 react 应用程序。

    为此,我们需要以这样的方式配置我们的路由,例如,如果用户点击 example.com/,我们会将 react 应用程序(静态 index.html)作为对浏览器的响应以及任何与example.com/api有关,我们会将响应对象发送回客户端。

    我们需要确保根据请求为请求/响应对象设置正确的标头。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-28
      • 1970-01-01
      • 2020-02-12
      • 2021-09-14
      • 2021-11-28
      • 2021-04-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多