0

我正在尝试通过 node.js 反向代理运行 NodeBB(https://docs.nodebb.org/configuring/proxies/node/

我已经按照每个教程、提示/提示进行了操作,但仍然遇到与我的 NodeBB 服务器的 websocket 连接问题,导致会话问题、无法登录等。

我的设置如下:

应用程序 1 - http://www.mywebsite.co.uk/

  • Node.js 和 Express
  • API 和前端网站的路由
  • 没有什么不寻常的
  • 帖子底部的完整代码段

我正在使用“http-proxy”npm 模块将任何加载http://mywebsite.co.uk/forum的人代理到http://www.myforum.co.uk/forum

这部分工作正常,资产按预期加载。但是,NodeBB 的一部分使用 websockets 来轮询论坛的功能目的,即用户会话。这部分代理不正确,或者至少 NodeBB 响应不正确,因此给了我很多错误:

“您正在从未知来源访问论坛。这可能会导致 websockets 无法连接。要解决此问题,请将"url" 值设置config.json为您访问该站点的 URL。有关更多信息,请参阅此常见问题解答主题: https: //community.nodebb.org/topic/13388 "

还:

“您与 NodeBB 的连接似乎已丢失,请稍候,我们正在尝试重新连接。”

而且,在网络面板中,许多“待处理”请求最终失败,NodeBB 的响应为空。

http://mywebsite.co.uk/forum/socket.io/?EIO=3&transport=polling&t=MgJQSMk


应用 2 - http://www.myforum.co.uk/forum

这个应用程序是一个基本的 NodeBB 安装运行,带有一个插件 - ( https://github.com/julianlam/nodebb-plugin-session-sharing )

配置 JSON 文件如下所示(请注意,根据代理时的说明,URL 是我的前端应用程序的 URL。

{
    "url": "http://www.mywebsite.co.uk/forum",
    "secret": "secret",
    "database": "postgres",
    "port": "4567",
    "postgres": {
        "host": "HOST",
        "port": "PORT",
        "password": "PASSWORD",
        "database": "DATABASE"
    }
}


应用程序 1 代码:

// app
const express = require("express");
const app = express();

app.use(require('cookie-parser')());
app.use(require('body-parser').urlencoded({ extended: true }));
app.use(require('express-session')({ secret: 'secret', resave: true, saveUninitialized: true }));

//
app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader(
    "Access-Control-Allow-Methods",
    "OPTIONS, GET, POST, PUT, PATCH, DELETE"
  );
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
  next();
});

// serve the content
app.use(express.static("dist"));

// Frontend
app.set('view engine', 'pug');

// serve out the api
// app.use ...

// Server set up
const httpProxy = require('http-proxy');
const HttpProxyRules = require('http-proxy-rules');

// Forum urls
let rules = {
  rules: {
    '/forum': 'http://www.myforum.co.uk/forum',
    '/forum/*': 'http://www.myforum.co.uk/forum',
  },
};

const proxyRules = new HttpProxyRules(rules);
const proxy = httpProxy.createProxy();

app.use(function (req, res, next) {
  try {
    if (req.url.includes("socket.io") === true) {
      // console.log("SOCKET.IO", req.url)
      return proxy.web(req, res, {
        target: 'wss://www.myforum.co.uk',
        ws: true,
        changeOrigin: true
      }, function (e) {
        // console.log('PROXY ERR', e)
        // next();
      });

    } else {
      var target = proxyRules.match(req);
      if (target) {
        // console.log("TARGET", target, req.url)
        return proxy.web(req, res, {
          target: target,
          changeOrigin: true
        }, function (e) {
          // console.log('PROXY ERR', e)
        });
      } else {
        next();
      }
    }
  } catch (e) {
    // res.sendStatus(500);
    res.json({ error: e });
  }
});

// Frontend routes
// app.use ...

// HTTP
const http = require('http');

// Create server
mainserver = http.createServer(app);

const PORT = process.env.PORT || 3000;
mainserver.listen(PORT);
mainserver.on('listening', onListening);
mainserver.on('error', function (error, req, res) {
  let json;
  console.log('proxy error', error);
  if (!res.headersSent) {
    res.writeHead(500, { 'content-type': 'application/json' });
  }

  json = { error: 'proxy_error', reason: error.message };
  res.end(JSON.stringify(json));
});

function onListening() {
  console.log(`Listening on :${PORT}`);
}

4

1 回答 1

1

为了解决这个问题,我更改了我正在使用的代理模块。它使用更少的代码来实现和使用 websockets。我认为 NodeBB Node.js 代理文档已过时,因此我将使用我找到的新方法进行更新。

工作代码如下:

/**
 * Proxy forum
 */
const proxy = require('http-proxy-middleware');

// Forum Proxy
app.use(
  '/forum',
  proxy({
    target: 'http://www.myforum.co.uk/forum',
    changeOrigin: true,
    ws: true,
  })
);

这里另一个潜在的问题是,这个 Prixy 设置需要在“body-parser”模块之上声明(如果正在使用)。错误的顺序将阻止发布请求被代理。

于 2019-06-11T08:56:27.980 回答