Как проверить URL в нижнем регистре и перенаправить, если они действительны с Lambda @ Edge - PullRequest
0 голосов
/ 02 октября 2019

У меня есть несколько старых 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 даже выполнять ввод / вывод?

И, что важно, может ли эта функция Lambda @ Edge работать только на 404 с?

1 Ответ

1 голос
/ 11 октября 2019

То, что вы написали, должно работать, но я думаю, что лучшей реализацией было бы просто изменить URI в OriginRequest лямбда-функции. Код такой простой, как:

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 @ Edge только для 404-х годов на данный момент.

Надеюсь, это поможет!

...