【问题标题】:Running frontend and backend on the same port在同一个端口上运行前端和后端
【发布时间】:2018-09-21 14:30:40
【问题描述】:

我今天遇到了一个与路由有关的问题。我有两个主要代码:一个是前端,另一个是后端。

前端是使用 Vue.js 编写的,所以它是一个 SPA。这个 web 应用有点复杂,涉及大量路由和后端 AJAX API 调用。

// All imports
import ...

loadMap(Highcharts);
loadDrilldown(Highcharts);
boost(Highcharts);

Vue.config.productionTip = false

Vue.use(VueCookie);
Vue.use(ElementUI, {locale});
Vue.use(VueRouter);
Vue.use(VueHighcharts, {Highcharts });
Vue.use(HighMaps);

// This is a global component declaration
Vue.component('app-oven', Devices);
Vue.component('app-sidebar', SideBar);
Vue.component('app-header', Header);
Vue.component('app-footer', Footer);
Vue.component('app-query', Query);
Vue.component('app-deviceproperties', DeviceProperties);
Vue.component('app-device', Device)
Vue.component('app-queryselection', QuerySelection)
Vue.component('app-index', Index)
Vue.component('app-index', Error)
Vue.component('app-realtime', RealTime);
Vue.component('app-login', Login)
Vue.component('app-preferences', Preferences)

const routes = [
  { path: '/index', component: Index},
  { path: '/', component: Login},
  { path: '/device/:deviceId', component: Device},
  { path: '/preferences', component: Preferences},
  { path: '*', component: Error}
];

const router = new VueRouter({
  routes: routes,
  mode: "history" // Gets rid of the # before the path
})

new Vue({
  el: '#app',
  router: router,
  components: { App },
  template: '<App/>'
})

后端是在 Node.js 上使用 Express 编写的,它响应来自前端的特定 AJAX 调用>.

// All imports
import ...

function prepareApp() {
    let app = new Express();

    app.use(cors({
        origin: "*",
        allowedHeaders: "Content-type",
        methods: "GET,POST,PUT,DELETE,OPTIONS" }));

    app.use(function(req, res, next) {
        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        next();
    });

    app.use(helmet());
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({extended: false}));

    // Get all parameters
    app.get('/params', params.parameters);
    // Get all devices ever seen on the databases
    app.get('/devices', params.devices);

    app.get('/organizeData', organizer.updateAll);

    // WebApp used services to access various things
    app.post('/customQuery', stats.query);
    app.post('/statistics', stats.statistics)
    app.post('/getUserInfo', stats.getUserInfo)
    app.post('/setUserInfo', stats.setUserInfo)
    app.post('/genericQuery', stats.genericQuery)
    app.post('/NOSQLQuery', stats.NOSQLQuery)

    // Users check and insertion
    app.get('/insertUser', stats.insertUser)
    app.post('/verifyUser', stats.verifyUser)

    app.get('/', errors.hello); // Returns a normal "hello" page
    app.get('*', errors.error404); // Catch 404 and forward to error handler
    app.use(errors.error); // Other errors handler

    return app;
}

let app = prepareApp();

//App listener on localhost:8080
app.listen(8080, () => {
    console.log("App listening on http://localhost:8080");
});

我只在开发过程中使用了这个设置,所以我让 both 在 localhost 上同时运行,两者使用不同的端口。现在我想开始制作周期,但我不知道从哪里开始。

最重要的是,我将这两个应用程序部署到一个在外部服务器上运行的V虚拟M机器上。它已经有一个 DNS 关联和一个静态 IP 地址,因此已经涵盖了。 当我尝试在这台生产机器上同时运行这两个程序时出现问题,因为它的开放端口只有端口 80 和端口 443。我认为这在生产环境中很正常,但我不知道如何调整我的应用程序,以便它们仍然可以相互通信并从数据库中检索有用信息同时仍然使用单个端口 .

我希望我能很好地解释这个问题。期待一个好的(也许很长的)答案。

【问题讨论】:

  • 你可以运行它 MEAN 风格,并让 nodejs 服务器为 Vue 应用程序提供服务

标签: node.js express vue.js production


【解决方案1】:

我建议在内部在端口 3000 上运行后端,并让 nginx 在 80 和 443 上侦听并将以 '/api' 开头的 url 代理到 3000 并直接交付前端,因为它只是一堆静态文件。

这将是您的 nginx 配置。只需确保后端服务器有一些 api 前缀,如“/api”。使用“npm run build”构建您的 vuejs 应用程序并将文件夹复制到 /opt/frontend。

upstream backend {
    server 127.0.0.1:3000;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    location /api/ {
        proxy_pass         http://backend;
        proxy_redirect     off;
        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-Host $server_name;
    }

    location / {
        root /opt/frontend/dist;
        try_files $uri $uri/ /index.html;
    }
}

或者,您可以使用后端来托管前端。但是,像 nginx 这样的网络服务器在提供静态文件方面比后端 api 服务器更有效。

【讨论】:

  • 感谢您的回答,非常简单明了。我今天要试试!
  • 经过一段时间摆弄设置后,我成功地设置了 nginx 服务并正确重定向到前端和后端。您的回答真的很有帮助,非常感谢!
【解决方案2】:

如果您无法打开更多端口,您可以将前端构建为生产模式,然后将其 index.html 和 dist 文件夹放到您的 nodejs 应用所在的同一文件夹中。 然后创建一个监听 80 端口的 express 应用并发送 HTML 文件。

var express = require('express');
var app = express();
var path = require('path');
var dir = '//vm//path//here';

app.get('/', function(req, res) {
    res.sendFile(path.join(dir + '/index.html'));
});

app.listen(80);

【讨论】:

  • 非常感谢您的快速回答!这正是我一直在寻找的东西,今天要尝试一下,看看效果如何!
【解决方案3】:

在我的情况下,我的后端服务器没有在集群模式下运行(例如,3001、3002...以及 80 端口)

我的案例:rails 服务器与乘客一起运行( mydomain.com ,80 端口) 我需要使用相同的域、相同的端口运行我的 Vuejs 项目。

所以唯一的解决方案是在指定的 URL 中运行 vue。

这是我的解决方案:

1.更改您的 nginx 配置。

http {
    # our backend app is passenger( rails server, running on 80 port)
    passenger_root /usr/local/rvm/gems/ruby-2.2.10/gems/passenger-6.0.0;
    passenger_ruby /usr/local/rvm/gems/ruby-2.2.10/wrappers/ruby;

    include       mime.types;
    default_type  application/octet-stream;

    server {
     listen 80;
     passenger_enabled on;
     # we are using this folder as the root of our backend app.
     root /mnt/web/php/public;
     charset utf-8;

     location ~ ^/(images|javascripts|stylesheets|upload|assets|video)/  {
       root /mnt/www/php/public;
       expires 30d;
       add_header Cache-Control public;
       add_header ETag "";
     }

     # vuejs related content
     location /vue.html {
       root   /mnt/web/vuejs/h5/dist;
     }
     location /static {
       root   /mnt/web/vuejs/h5/dist;
     }
    }
}

2.在你的vue项目的dist文件夹中:

$ mv index.html vue.html

3.vuejs 项目中所有请求的 url 都应该根据 nginx 配置进行更改。

【讨论】:

    猜你喜欢
    • 2023-04-07
    • 2021-05-22
    • 2019-06-29
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 2021-12-16
    • 2020-09-14
    • 2014-09-23
    相关资源
    最近更新 更多