繁体   English   中英

NestJS 基于浏览器语言交付静态文件

[英]NestJS deliver static files based on language of browser

Nestjs 应该提供基于浏览器中定义的语言的 Angular 应用程序。

Angular 应用程序位于dist/public/endist/public/de

如果用户使用英文浏览器访问/ ,nestjs 应该从文件夹dist/public/en传送文件。 在这种情况下,浏览器中的路径应该指向fqdn/en/

我已经在单语言 Angular App 中使用了它:

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);

  app.useStaticAssets(join(__dirname, 'public'));
  await app.listen(process.env.PORT || 3000);
}
bootstrap();

我还查看了i18next ,它看起来很有希望。

但我不确定这是否是正确的方向。

任何提示都受到热烈欢迎。

比静态提供dist文件夹更好的是将所有非 api 路由重定向到index.html以便您的 Angular SPA 可以处理路由。 有关更多详细信息,请参阅此答案


您可以通过考虑要检测用户语言的因素(例如ACCEPT-LANGUAGE标头或某个 cookie)来调整上面链接答案中的中间件:

@Middleware()
export class FrontendMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: Function) {
    // Some way of detecting the user's language
    const languages = req.header('ACCEPT-LANGUAGE') || 'en-US';

    if (languages.contains('de-DE')) {
      res.sendFile(join(__dirname, 'public', 'de' ,'index.html'));
    } else {
      res.sendFile(join(__dirname, 'public', 'en', 'index.html'));
    }
  }
}

@kim-kern 非常感谢您的回答。 它把我推向了正确的方向。

我现在通过以下方式解决了这个问题:maint.ts 将基于全局中间件进行语言检测并定义文件的静态交付:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as compression from 'compression';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
const i18next = require('i18next');
const middleware = require('i18next-http-middleware');

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);

  i18next.use(middleware.LanguageDetector).init({
    detection: {
      order: ['path', 'session', 'querystring', 'cookie', 'header'],
    },
  });

  app.use(
    middleware.handle(i18next, {
      ignoreRoutes: ['/api'],
      removeLngFromUrl: false,
    }),
  );

  app.useStaticAssets(join(__dirname, 'public'));
  app.use(compression());
  await app.listen(process.env.PORT || 3000);
}
bootstrap();

我定义了一个自定义中间件,用于检查找到的语言,并根据 baseUrl 提供正确的 index.html 文件:

import { NestMiddleware, Injectable } from '@nestjs/common';
import { Request, Response } from 'express';
import { join } from 'path';

@Injectable()
export class FrontendMiddleware implements NestMiddleware {
  use(req: any, res: Response, next: Function) {
    if (req.lng && !req.baseUrl && req.lng.startsWith('de')) {
      res.sendFile(join(__dirname, 'public', 'de', 'index.html'));
    } else if (!req.baseUrl) {
      res.sendFile(join(__dirname, 'public', 'en', 'index.html'));
    } else {
      next();
    }
  }
}

然后将自定义中间件包含在 app.module.ts 中:

...
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer): void {
    consumer.apply(FrontendMiddleware).forRoutes({
      path: '/**',
      method: RequestMethod.ALL,
    });
  }
}

现在唯一开放的问题是它总是尝试从固定目录 public 传递文件,如果在开发模式而不是生产模式下运行会失败。

我会在那里寻找解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM