【问题标题】:How to check lowercased URLs and redirect if they're valid with Lambda@Edge如何检查小写 URL 并重定向它们是否对 Lambda@Edge 有效
【发布时间】:2019-10-12 03:52:45
【问题描述】:

我有一些过去使用大写字母表示人名等的旧 URL,但现在我已将我的网站更新为在每个页面的 URL 中只使用小写字符。所以,如果人们碰巧点击了旧链接,或者不小心输入了大写字母,我想重定向他们。

我还检查删除尾部斜杠。这是我目前在前端使用的代码。我希望切换到使用 Lambda@Edge(我的网站在 S3 上并通过 CloudFront 分发)进行检查和重定向。

这是我在前端使用的 JS 函数:

var newUrl = window.location.href.toLowerCase().replace(/\/$/, '')

loadIfChanged(newUrl)

function loadIfChanged (newUrl) {
  if (newUrl != location.href) {
    fetch(newUrl, {method: 'HEAD'}).then(function (response) {
      if (response.status === 200) return window.location = newUrl
    }).catch(function (error) {
      return console.log(error)
    })
  }
}

我如何在 Lambda@Edge 函数中编写它?

可能是这样的:

exports.handler = async function (event, context) {
  // Lowercase the URL and trim off a trailing slash if there is one
  var path = event.Records[0].cf.request.uri.toLowerCase().replace(/\/$/, '')

  // How to do a fetch here? var ok = fetch()

  if (ok) {
    const response = {
      status: '301',
      statusDescription: 'Moved Permanently',
      headers: {
        location: [{
          key: 'Location',
          value: `https://example.com/${path}`,
        }],
      },
    }
    return response
  } else {
    return event.Records[0].cf.request
  }
}

Lambda@Edge 函数甚至可以进行 I/O 吗?

而且,重要的是,这个 Lambda@Edge 函数是否只能在 404 上运行?

【问题讨论】:

    标签: javascript aws-lambda-edge


    【解决方案1】:

    你写的应该可以,但我认为更好的实现是简单地更改 OriginRequest Lambda 函数中的 URI。代码很简单:

    import json
    
    def lambda_handler(event, context):
        request = event['Records'][0]['cf']['request'];
        request['uri'] = "anything";
    
        return request;
    

    这里要注意的一个有趣的细节是,CF 将根据原始 URI 缓存修改 URI 的结果。因此,如果再次请求原始 URI,CloudFront 将直接从缓存中返回响应。

    为什么是原始请求?

    1. 因为它仅在缓存未命中时触发
    2. 它有助于获得上述缓存的好处

    为什么这种方式比您建议的方式更好?
    如果您决定采用上述方法,以下是请求流程:
    对于非缓存内容:

    User -> CF -> Lambda -> S3 -> Final response to the user   
    

    对于缓存的内容:

    User -> CF -> Final response to the user   
    

    而如果您使用 Lambda 生成 301,流程将是:
    对于非缓存内容:

    User -> CF -> Lambda -> User -> CF -> Lambda -> S3 -> Final response to the user  
    

    对于缓存的内容:

    User -> CF(cf returns 301) -> User -> CF -> Final response to the user  
    

    所以你在这种方法中有两个好处:

    1. 为您的用户减少延迟。
    2. 更少的 lambda 调用,这意味着对您来说更少的费用。

    关于您的第二个问题,我认为目前没有任何方法可以仅针对 404 调用 Lambda@Edge。

    希望这会有所帮助!

    【讨论】:

    • 所以,本质上,我在 CloudFront 需要访问源的任何时候通过将它们小写并去掉尾随逗号(这就是我所做的)来强制执行 URL 格式。然后该响应被兑现,无论它是否是 404?
    • 哈!我厌倦了这个,现在字体和图像丢失了。猜猜我忘记了 Camel 大小写的 JavaScript 文件和带有大写字母的图像以及字体文件。此外,URL 不会被重写,它会保持用户输入的方式。似乎需要重定向。
    猜你喜欢
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 2019-12-01
    • 1970-01-01
    • 2019-07-25
    相关资源
    最近更新 更多