NodeJS 如何避免在快速路径中自动添加斜线?

z31licg0  于 2023-03-07  发布在  Node.js
关注(0)|答案(1)|浏览(101)

我已经在寻找解决办法了,但不幸的是没有一个奏效。也许你能帮助我。
我正在用Node.JS和Express编写一个基于插件的Web服务器。主要的Web服务器代码如下所示:
在这一部分,所有的插件都被初始化了,主服务器的所有路由都被初始化了。下面是插件和主服务器的编译

const express = require('express');
const path = require('path');
const fs = require('fs');

const settings = require('../settings/settings');

// Events
const events = require('./functions/events/events');

// Webserver
const app = express();

// Ordnerpfade definieren
const pluginsPath = path.join(__dirname, 'plugins');
const publicPath = path.join(__dirname, 'public');
const routesPath = path.join(__dirname, 'routes');
const viewsPath = path.join(__dirname, 'views');

// ETA RENDER ENGINE
const eta = require('eta');
eta.configure({
  views: viewsPath,
  useWith: true,
  autoEscape: true,
  cache: false
});
app.set('view engine', 'eta');

// Öffentliche Ressourcen des Webservers
app.use(express.static(publicPath, {
  redirect: false
}));

// Plugins einbinden
global.plugins = {};
global.plugins.pluginData = {};
var pluginsActive = {};   //aktive Plugins
var pluginSettings = [];  // Settings einzelner Plugins
var pluginAssets = [];    // Assets einzelner Plugins

var pluginData = [];

function filterDirectories(dir) {
  return fs.lstatSync(path.join(pluginsPath, dir)).isDirectory();
}

function getFilesInDirRec(fileExtension, pluginPublicFolder, dirPath, ignoredDirs, pluginName) {
  let files = [];
  fs.readdirSync(dirPath).forEach((file) => {
    const filePath = path.join(dirPath, file);
    const fileStat = fs.statSync(filePath);
    if (fileStat.isDirectory()) {
      if (!ignoredDirs.includes(file)) {
        const subDirFiles = getFilesInDirRec(
          fileExtension,
          pluginPublicFolder,
          filePath,
          ignoredDirs,
          pluginName
        );
        files = files.concat(subDirFiles);
      }
    } else if (file.endsWith(`.${fileExtension}`)) {
      var assetPath = path.join("/", pluginName, path.relative(pluginPublicFolder, filePath));
      files.push(assetPath);
    }
  });
  return files;
}

fs.readdirSync(pluginsPath).filter(filterDirectories).forEach(pluginName => {
  pluginData[pluginName] = {};

  // Pfad zum Plugin
  const pluginPath = path.join(pluginsPath, pluginName);

  // Öffentliche Ressourcen des Plugins
  const pluginPublicPath = path.join(pluginPath, 'public');
  if (fs.existsSync(pluginPublicPath)) {
    app.use(`/${pluginName}`, express.static(pluginPublicPath, {
      redirect: false
    }));
  }
  
  // Routen des Plugins
  const pluginRoutesPath = path.join(pluginPath, 'routes');
  if (fs.existsSync(pluginRoutesPath)) {
    fs.readdirSync(pluginRoutesPath).forEach(routeName => {
      routeName = routeName.split('.')[0];
      if(routeName === "index"){ routeName = ""}
      const router = require(path.join(pluginRoutesPath, routeName));
      app.use(path.join('/', pluginName, routeName), router);
    });
  }
  
  // Views des Plugins
  const pluginViewsPath = path.join(pluginPath, 'views');
  if (fs.existsSync(pluginViewsPath)) {
    app.set(`views`, [pluginViewsPath, viewsPath]);
  }

  // JS und CSS Dateien des Plugins auslesen
  const ignoredDirNames = ["helper"];
  const pluginJSfiles = getFilesInDirRec(   "js", pluginPublicPath, path.join(pluginPublicPath,   'js'), ignoredDirNames, pluginName);
  const pluginCSSfiles = getFilesInDirRec(  "css", pluginPublicPath, path.join(pluginPublicPath,  'css'), ignoredDirNames, pluginName);
                                            // Dateiendung                                        // Unterordner in "plugin/public"
  pluginData[pluginName].assets = {};                                          
  pluginData[pluginName].assets.css = pluginCSSfiles;
  pluginData[pluginName].assets.js = pluginJSfiles;

  // Settings des Plugins
  const pluginsSettingsPath = path.join(pluginPath, 'settings');
  if (fs.existsSync(pluginsSettingsPath)) {
    const thisPluginSettings = require(`${pluginsSettingsPath}/pluginSettings`);
    pluginData[pluginName].settings = thisPluginSettings;
  }
  
  // Alle aktivierten Plugins global speichern
  pluginsActive[pluginName] = true;
  
});

global.plugins.active = pluginsActive;
global.plugins.pluginData = pluginData;

// Middleware
const middleware = require('./middleware/middleware');

// Routen des Webservers hinzufügen
fs.readdirSync(routesPath).forEach(routeName => {
  routeName = routeName.split('.')[0];
  if(routeName === "index"){ routeName = ""}
  const router = require(path.join(routesPath, routeName));
  app.use(`/${routeName}`, router);
});


// Handle 404
app.use(function(req, res) {
  if (res.headersSent) {
      return;
  }
  res.status(404);
  res.render("404", {});
});

const start = function() {
  // Webserver starten
  app.listen(settings.server.port, () => {
    console.log('Webserver gestartet unter Port: ' + settings.server.port);
  });
};

module.exports = {
  start
};

下面是Web服务器的路由indextest

const express = require('express');
const router = express.Router({ strict: true });
const eta = require('eta');
const path = require('path');

const viewsPath = path.join(__dirname, '..', 'views');
eta.configure({
  views: viewsPath
});

const middleware = require('../middleware/middleware');

// Router-Instanz in Middleware-Funktion umwandeln
const pluginRouter = express();
pluginRouter.use(router);


// Eine Route-Instanz definieren
router.get('/', [middleware.plugins.getActivePlugins, middleware.metaData.getMetaDataSkeleton], async (req, res, next) => {
  
  var templateData = {};
  templateData = req.middlewareData.templateData;
  
  templateData.metaData.title = templateData.metaData.app.name + " - Startseite";
  
  templateData.metaData.customMetaTags.push({
    proberty: "test",
    oder: true,
    but: "no"
  });
  
  console.log(templateData);
  eta.renderFile('index', templateData)
  .then(html => {
    res.send(html);
  })
  .catch(err => {
    console.error(err);
    res.sendStatus(500);
  });

});

// Eine Route-Instanz definieren
router.get('/test', [middleware.plugins.getActivePlugins, middleware.metaData.getMetaDataSkeleton], async (req, res, next) => {
  
  var templateData = {};
  templateData = req.middlewareData.templateData;
  
  templateData.metaData.title = templateData.metaData.app.name + " - Startseite";
  
  templateData.metaData.customMetaTags.push({
    proberty: "test",
    oder: true,
    but: "no"
  });
  
  console.log(templateData);
  eta.renderFile('index', templateData)
  .then(html => {
    res.send(html);
  })
  .catch(err => {
    console.error(err);
    res.sendStatus(500);
  });

});



module.exports = pluginRouter;

当我调用那里的一条路由时,无论是https://example.cc还是https://example.cc/test-链接都不会改变,保持原样。
然而,当我调用插件的路由时,例如https://example.cc/bloghttps://example.cc/tags,斜线/总是自动添加到链接的末尾,结果为https://example.cc/blog/https://example.cc/tags/ Google Chrome中的开发者控制台说,有一个301重定向到末尾为/的页面。
下面是插件的一个路由的代码:

const path = require("path");
const express = require('express');
const router = express.Router();
const eta = require('eta');

const viewsPath = path.join(__dirname, "..", 'views');
eta.configure({
  views: viewsPath
});

// Registrieren des Event-Listeners
const events = require('../../../functions/events/events');

// Plugin Router Initialisieren
const pluginRouter = express();
pluginRouter.use(router);

// GLOBAL MIDDLEWARE
const middleware = require('./../../../middleware/middleware');

// LOCAL MIDDLEWARE
const pluginMiddleware = require('./../middleware/pluginMiddleware');
const testMiddleware = pluginMiddleware.test;

// Eine Route-Instanz definieren
router.get('/', [middleware.plugins.getActivePlugins, middleware.metaData.getMetaDataSkeleton, testMiddleware], (req, res, next) => {
  var templateData = {};
  templateData = req.middlewareData.templateData;

  templateData.metaData.title = templateData.metaData.app.name + " - Blog";

  console.log(templateData);
  // Auslösen eines Events
  events.emitter.emit('getBlogIndex', {
    eventData: "is-test"
  });

  // Rendern einer Datei
  eta.renderFile(path.join(viewsPath, 'index'), templateData)
  .then(html => {
    res.send(html);
  })
  .catch(err => {
    console.error(err);
    res.sendStatus(500);
  });

});



module.exports = pluginRouter;

无论我尝试什么,都没有效果。它总是在插件中进行301重定向到同一页面,但有额外的/
我尝试了以下方法:
我读到这与静态文件有关。每个插件都有自己的静态文件夹。该目录与插件路由目录处于同一级别。https://expressjs.com/en/4x/api.htmlExpress adds slash at the end of url weirdly
所以我试着将选项redirect设置为false。不幸的是,这并没有带来任何成功。
对于插件:

// Öffentliche Ressourcen des Plugins
  const pluginPublicPath = path.join(pluginPath, 'public');
  if (fs.existsSync(pluginPublicPath)) {
    app.use(`/${pluginName}`, express.static(pluginPublicPath, {
      redirect: false
    }));
  }

对于主Web服务器

// Öffentliche Ressourcen des Webservers
app.use(express.static(publicPath, {
  redirect: false
}));

然后我也试着在插件路由器中设置strict选项,这也不起作用。
Express adds slash at the end of url weirdly
在每条路线中

const router = express.Router({ strict: true });

我也尝试了两者的组合。没有什么会导致路由停止做301转发。
除此之外,我还尝试了这个选项:Trailing slash gets appended to url in express server
在主Web服务器初始化时

app.enable('strict routing');

可惜也没什么用。我不知道还能找什么。你能帮我吗?因为我来这里很不幸没有更远。会很高兴的!亲切的问候。
我正在使用快捷方式^4.18.2

cuxqih21

cuxqih211#

休息了几个小时后,我重新审视了这个问题,并解决了它。这是一个偶然的机会,但我在Chrome开发者控制台中看到,该页面是从磁盘缓存加载的。这就是为什么我的尝试失败的全部问题。

所以我重复了我失败的尝试,解决方案很简单。我只是在插件路径中添加了这一行:

const router = express.Router({ strict: true });

我开始隐姓埋名的模式是为了有一个原始的环境。看,一切都像它应该的那样工作。
现在我可以通过http://example.cc/bloghttp://example.cc/blog/访问每个路由,没有任何区别。
我没想到在服务器上调用的操作也会以某种方式缓存在客户端上,这里只是一个链接,但这足以让我忙上一阵子。
干杯。

相关问题