Specify the character code (charset) in the Content-Type field of the HTTP response header using AWS CDK.

2022.08.23

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

INTRODUCTION:

In modern web browsers where multi-language web applications are getting popular to display a web page correctly, the web browser must know which character set to use. The character set declaration plays a crucial role when your web application has native languages other than English to render in the web browser. In my use case, I am trying to render Japanese and English content in my web application, and I need to specify a key to encode the text which is called Character-encoding. The character set includes letters, numbers, and special characters. By specifying your content as character UTF-8 the browser will encode and decode properly to display the content over the browser. Hence, your browser won’t misinterpret the information that you are rendering in your native language.

Most of the time the content is getting pulled from the server via API calls. So you need to set the character code (charset) in the Content-Type field of the HTTP response header, like "Content-Type: text/html; charset=UTF-8".

In this blog, we are using AWS CDK for Iac(Infrastructure as code). We are setting response headers to CloudFront using Lambda@Edge function.

Add Lambda@Edge as the origin response with the following content.

iac/lib/lambda-edges/line-app-web-viewer-response.js

'use strict';
exports.handler = (event, context, callback) => {
  const response = event.Records[0].cf.response;
  const headers = response.headers;

  if (headers['content-type']?.[0]?.value === 'text/html') {
    headers['content-type'] = [
      { key: 'Content-Type', value: 'text/html; charset=UTF-8' },
    ];
  }

  callback(null, response);
};

Add the header function under the cdk stack and notify the same in the cloud distributions.

iac/lib/web-stack.ts

const addHeadersFn = new cloudfront.experimental.EdgeFunction(
  this,
  'addHeadersFn',
  {
    code: lambda.Code.fromAsset(path.join(__dirname, './lambda-edges')),
    handler: 'line-app-web-viewer-response.handler',
    runtime: lambda.Runtime.NODEJS_16_X,
  }
);

Now add the below code under cloudfront distribution's defaultBehavior.

edgeLambdas: [
  {
    eventType: cloudfront.LambdaEdgeEventType.ORIGIN_RESPONSE,
    functionVersion: addHeadersFn.currentVersion,
  },
];

Result

Now for any given page we can see the Content-Type set to text/html; charset=UTF-8. This ensures UTF-8 encoding for the content to be righty determined.

reference

  • https://dev.classmethod.jp/articles/lambda-edge-content-type-charset-utf-8/
  • https://www.tutorialspoint.com/aws_lambda/aws_lambda_using_aws_lambdaedge_with_cloudfront.htm
  • https://www.w3.org/International/questions/qa-choosing-encodings