1

我有一个 Lambda Edge 附加到应该处理重定向的 Origin Request 事件。代码非常简单,它检查请求的 URL 是否在 DynamoDB 表中,如果是,则返回带有重定向 URL 的 301 响应。这是我拥有的 Lambda Edge 代码

const aws = require("aws-sdk");
const dynamoDB = new aws.DynamoDB.DocumentClient();
exports.handler = async (event, context, callback) => {
  const request = event.Records[0].cf.request;
  const uri = request.uri;

  let redirect = await getRedirect(uri);
  if (redirect) {
    const redirectResponse = createRedirect(redirect.To);
    callback(null, redirectResponse);
    return;
  }
  callback(null, request);
  return request;
};

function getRedirect(uri) {
  let params = {
    TableName: "Redirects",
    KeyConditionExpression: "#from = :from",
    ExpressionAttributeNames: {
      "#from": "From"
    },
    ExpressionAttributeValues: {
      ":from": uri
    }
  };
  return dynamoDB
    .query(params)
    .promise()
    .then(result => result.Items[0])
    .catch(reject => null);
}

function createRedirect(uri) {
  const response = {
    status: "302",
    statusDescription: "Found",
    headers: {
      "cache-control": [
        {
          key: "Cache-Control",
          value: "max-age=0"
        }
      ],
      location: [
        {
          key: "Location",
          value: uri
        }
      ]
    }
  };
  return response;
}

如果我使用测试事件测试 Lambda 函数,我会收到重定向响应。但是,当我尝试使用 CloudFront 进行重定向时,出现 403 错误。所以,假设 URL/a应该重定向到/b. 如果我打电话cloudfront.url/a,我应该会收到一条消息,说明该对象已被移动到/b(或者甚至更好地被自动重定向)。相反,我得到了 403 错误。Lambda 是否有问题,或者我需要向 CloudFront 附加一些权限才能使重定向正常工作?

4

1 回答 1

1

感谢 Niobos 的帮助,我弄清楚了问题所在。问题在于 DynamoDB 区域。我的 Lambda Edge 函数在 eu-central-1 上运行,这是离我所在位置最近的边缘,但 DynamoDB 表在 us-east-1 中。所以我把我的代码改成了这个,一切正常:)

const aws = require("aws-sdk");
const dynamoDB = new aws.DynamoDB.DocumentClient({ region: "us-east-1" });
exports.handler = async (event, context, callback) => {
  const request = event.Records[0].cf.request;
  const uri = request.uri;

  let redirect = await getRedirect(uri);
  if (redirect) {
    const redirectResponse = createRedirect(redirect.To);
    callback(null, redirectResponse);
    return;
  }
  callback(null, request);
  return request;
};

function getRedirect(uri) {
  let params = {
    TableName: "Redirects",
    KeyConditionExpression: "#from = :from",
    ExpressionAttributeNames: {
      "#from": "From"
    },
    ExpressionAttributeValues: {
      ":from": uri
    }
  };
  return dynamoDB
    .query(params)
    .promise()
    .then(result => result.Items[0])
    .catch(reject => null);
}

function createRedirect(uri) {
  const response = {
    status: "302",
    statusDescription: "Found",
    headers: {
      "cache-control": [
        {
          key: "Cache-Control",
          value: "max-age=0"
        }
      ],
      location: [
        {
          key: "Location",
          value: uri
        }
      ]
    }
  };
  return response;
}
于 2020-01-07T15:21:01.970 回答