运行 前后端在同一个端口
Running frontend and backend on the same port
我今天遇到了一个与路由有关的问题。我有两个主要代码:一个是前端,另一个是后端。
前端是使用 Vue.js 编写的,因此它是一个 SPA。这个 webapp 有点复杂,涉及很多路由和后端 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 来自 Frontend.
的调用
// 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 运行ning 都使用了不同的端口。现在我想开始 production 周期,但我不知道从哪里开始。
最重要的是,我将这两个应用程序部署到 V虚拟 M 机器上,该机器 运行 在外部服务器上运行.它已经有一个 DNS 关联和一个静态 IP 地址,因此已经包含在内。
当我尝试在这台生产机器上同时 运行 两个程序时出现问题,因为它的开放端口只有端口 80 和端口 443 。我认为这在生产环境中很正常,但我不知道如何调整我的应用程序,以便它们仍然可以相互通信并从数据库中检索有用的信息,同时仍然使用单个端口.
我希望我能很好地解释这个问题。期待一个不错的(也许很长)答案。
我推荐 运行 内部端口 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 服务器更有效。
如果您无法打开更多端口,可以将前端构建为生产模式,然后将其 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);
就我而言,我的后端服务器没有 运行 集群模式(例如 3001、3002... 以及 80 端口)
我的情况:rails服务器运行乘客(mydomain.com,80端口)
我需要 运行 我的 Vuejs 项目具有相同的域,相同的端口。
所以唯一的解决方案是 运行 vue 在指定的 URL 中。
这是我的解决方案:
1.change 你的 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.in 你的 vue 项目的 dist
文件夹:
$ mv index.html vue.html
3.all 在你的 vuejs 项目中请求的 url 应该根据 nginx 配置进行更改。
我今天遇到了一个与路由有关的问题。我有两个主要代码:一个是前端,另一个是后端。
前端是使用 Vue.js 编写的,因此它是一个 SPA。这个 webapp 有点复杂,涉及很多路由和后端 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 来自 Frontend.
的调用// 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 运行ning 都使用了不同的端口。现在我想开始 production 周期,但我不知道从哪里开始。
最重要的是,我将这两个应用程序部署到 V虚拟 M 机器上,该机器 运行 在外部服务器上运行.它已经有一个 DNS 关联和一个静态 IP 地址,因此已经包含在内。 当我尝试在这台生产机器上同时 运行 两个程序时出现问题,因为它的开放端口只有端口 80 和端口 443 。我认为这在生产环境中很正常,但我不知道如何调整我的应用程序,以便它们仍然可以相互通信并从数据库中检索有用的信息,同时仍然使用单个端口.
我希望我能很好地解释这个问题。期待一个不错的(也许很长)答案。
我推荐 运行 内部端口 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 服务器更有效。
如果您无法打开更多端口,可以将前端构建为生产模式,然后将其 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);
就我而言,我的后端服务器没有 运行 集群模式(例如 3001、3002... 以及 80 端口)
我的情况:rails服务器运行乘客(mydomain.com,80端口) 我需要 运行 我的 Vuejs 项目具有相同的域,相同的端口。
所以唯一的解决方案是 运行 vue 在指定的 URL 中。
这是我的解决方案:
1.change 你的 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.in 你的 vue 项目的 dist
文件夹:
$ mv index.html vue.html
3.all 在你的 vuejs 项目中请求的 url 应该根据 nginx 配置进行更改。