【问题标题】:AWS Cloudfront distribute multilingual angular appsAWS Cloudfront 分发多语言 Angular 应用程序
【发布时间】:2018-08-10 12:30:41
【问题描述】:

我有一个 Angular 应用程序,它存储在 AWS S3 存储桶中并由 Cloudfront 分发。

现在我想以多种语言分发我的应用程序。我已经翻译了我的 Angular 应用程序以及我正在构建的每种语言。

所以我的 S3 存储桶如下所示:

de
   /index.html
   /script.js
en
   /index.html
   /script.js

对于每种语言,我想为另一个应用提供服务。

在 Cloudfront 中,我创建了两个指向 Origin Path /de/en 的 Origins

所以我的 URL 架构是这样的:

<appname>.<mydomain>.com/:lang

但我的问题是,我没有让错误页面与这些特定的语言文件夹一起使用。 当发生 404(由于重新加载)时,我需要这些错误响应处理程序来提供 Angular 应用程序

有谁知道我该如何解决这个问题?还是我应该为每种语言再创建一个子域?所以它看起来像这样:

<lang>.<appname>.<mydomain>.com

【问题讨论】:

    标签: angular internationalization amazon-cloudfront


    【解决方案1】:

    我最近遇到了同样的问题。我的情况:

    • 我有一个 Angular 5 应用程序
    • 我将 i18n 用于 2 种语言(英语和法语)
    • S3 用于网站托管,Cloudfront 用于 CDN 和自定义域名/ssl 证书
    • 我的默认语言是 EN,所以 https://example.com 重定向到 https://example.com/en/
    • 当用户直接导航到某个路线(例如https://example.com/en/product/1234)时,它也应该可以工作,而与子文件夹的数量无关

    解决方案:

    • 创建 2 个单独的部署,每种语言 1 个(英语、法语)。 Git bash 倾向于将 /en/ 替换为本地文件夹,因此请确保您的 index.html 文件包含正确的基本 url

    ng build -prod -aot --base-href /en/ --i18nFile=src/locale/messages.en.xlf --i1nFormat=xlf --locale=en

    • 将它们部署到 S3 存储桶根目录下的 /en/ 和 /fr/ 文件夹中
    • 创建新的 CloudFront 分配。确保将 Default Root Object 留空!
    • 将您的存储桶添加为 S3 源(如您所愿)。
    • 现在,创建一个新的 Lambda 函数,使用 Node 6.10。重要提示:选择 US-EAST-1,因为这是 Lambda@Edge 支持的唯一区域。代码:

    const path = require('path')
    
    exports.handler = (evt, ctx, cb) => {
      const { request } = evt.Records[0].cf
    
      if (!path.extname(request.uri)) {
          if (request.uri.startsWith('/fr'))
            request.uri = '/fr/index.html'
          else
            request.uri = '/en/index.html'
      }
      cb(null, request)
    }
    • 下一步:发布此版本(在操作下拉列表中)
    • 复制此版本的 ARN,然后返回 CloudFront -> 行为 -> 默认行为
    • 在 Lambda 函数关联中选择 Origin Request 作为事件类型,然后粘贴 Lambda 函数的 ARN。

    使用基本路径参数构建 Angular 将为您的 Angular 应用程序建立正确的子目录。重写将确保资源文件不会被重写,但您的所有路由将被重定向到 index.html

    【讨论】:

    • 感谢您的详细解答!您是否注意到由于 lambda 函数而导致的任何延迟?我希望没有一个解决方案
    • 不,我没有注意到任何延迟。此外,它仅在缓存未命中时触发。
    • 自 Angular 6+ 以来部署语法发生了变化(使用 angular.json 配置),但底层方法仍然有效。
    • 当这实际上是 URL 重写时,您正在谈论重定向。用户的地址栏不会改变。这也意味着 GET /fruits 将与 S3 中的 /fr/index.html 相关联,这可能不是您想要的。您可能应该使用request.uri === '/fr' || request.uri.startsWith('/fr/') 进行测试。
    【解决方案2】:

    我遇到了同样的问题,但也想在去的时候自动重定向到最接近的语言

    <mydomain>.com/
    

    使用 Dries Van Hansewijck 的解决方案和 npm 的 locale 包,您可以使用以下代码进行重定向:

    const path = require('path');
    const locale = require("locale");
    const supportedLocales = new locale.Locales(['en', 'de']);
    locale.Locale["default"] = new locale.Locales('de');
    
    module.exports.pendixPortalI18n = (event, context, callback) => {
      const { request } = event.Records[0].cf;
      const locale = getBestLocale(request);
      if (!path.extname(request.uri)) {
        console.log(JSON.stringify(event, null, 2));
        if (request.uri.startsWith('/en')) {
          console.log('ENGLISH detected')
          request.uri = '/en/index.html';
        } else if (request.uri.startsWith('/de')) {
          console.log('GERMAN detected')
          request.uri = '/de/index.html';
        } else {
          console.log('Default matching locale is ' + locale);
          request.uri = `/${locale}/index.html`;
        }
      }
      callback(null, request)
    };
    
    function getBestLocale(request) {
      /* First we try to find the accept-language value */
      if (request && request.headers
        && request.headers['accept-language'] && request.headers['accept-language'].length > 0
        && request.headers['accept-language'][0].value) {
        const acceptLanguage = request.headers['accept-language'][0].value;
        const locales = new locale.Locales(acceptLanguage);
        const bestMatch = locales.best(supportedLocales);
        console.log("You asked for: " + JSON.stringify(acceptLanguage));
        console.log("We support: " + supportedLocales);
        console.log("Our default is: " + locale.Locale["default"]);
        console.log('best match is ' + bestMatch);
        return bestMatch;
      }
      return 'de';
    }
    

    这里我们尝试在支持的语言列表中查找用户的语言。为此,您需要将接受语言标头转发到云端的源(在行为选项卡中)。如果用户的语言不在支持的语言列表中,我们会重定向到德语。

    【讨论】:

      猜你喜欢
      • 2015-12-14
      • 2014-09-18
      • 2021-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-04
      • 2012-03-21
      相关资源
      最近更新 更多