0
0

More than 3 years have passed since last update.

Amazon Web Service ブログがバグっててハマった件〜画像をリサイズする〜

Last updated at Posted at 2019-12-27

お疲れ様です。

早速本題ですが

CloudFrontとLambda@Edgeを利用して画像をリサイズする方法を採用しようと思い、
以下のブログを参考に、リサイズするところまでは実装できたのですが、
横幅と縦幅にnullを設定したいなーと修正していたところ、掲載されているコードにバグがありハマりました。

Amazon CloudFront & Lambda@Edge で画像をリサイズする


'use strict';

const querystring = require('querystring');

// defines the allowed dimensions, default dimensions and how much variance from allowed
// dimension is allowed.

const variables = {
    allowedDimension : [
        {w:100,h:100},
        {w:200,h:200},
        {w:300,h:300},
        {w:400,h:400}
    ],
    defaultDimension : {w:200,h:200},
    variance: 20,
    webpExtension: 'webp'
};

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

    // parse the querystrings key-value pairs. In our case it would be d=100x100
    const params = querystring.parse(request.querystring);

    // fetch the uri of original image
    let fwdUri = request.uri;

    // if there is no dimension attribute, just pass the request
    if(!params.d){
        callback(null, request);
        return;
    }
    // read the dimension parameter value = width x height and split it by 'x'
    const dimensionMatch = params.d.split("x");

    // set the width and height parameters
    let width = dimensionMatch[1];
    let height = dimensionMatch[2];

    // parse the prefix, image name and extension from the uri.
    // In our case /images/image.jpg

    const match = fwdUri.match(/(.*)\/(.*)\.(.*)/);

    let prefix = match[1];
    let imageName = match[2];
    let extension = match[3];

    // define variable to be set to true if requested dimension is allowed.
    let matchFound = false;

    // calculate the acceptable variance. If image dimension is 105 and is within acceptable
    // range, then in our case, the dimension would be corrected to 100.
    let variancePercent = (variables.variance/100);

    for (let dimension of variables.allowedDimension) {
        let minWidth = dimension.w - (dimension.w * variancePercent);
        let maxWidth = dimension.w + (dimension.w * variancePercent);
        if(width >= minWidth && width <= maxWidth){
            width = dimension.w;
            height = dimension.h;
            matchFound = true;
            break;
        }
    }
    // if no match is found from allowed dimension with variance then set to default
    //dimensions.
    if(!matchFound){
        width = variables.defaultDimension.w;
        height = variables.defaultDimension.h;
    }

    // read the accept header to determine if webP is supported.
    let accept = headers['accept']?headers['accept'][0].value:"";

    let url = [];
    // build the new uri to be forwarded upstream
    url.push(prefix);
    url.push(width+"x"+height);

    // check support for webp
    if (accept.includes(variables.webpExtension)) {
        url.push(variables.webpExtension);
    }
    else{
        url.push(extension);
    }
    url.push(imageName+"."+extension);

    fwdUri = url.join("/");

    // final modified url is of format /images/200x200/webp/image.jpg
    request.uri = fwdUri;
    callback(null, request);
};

console.log(height);

↑を仕込んで確認していたところ、ループの手前までheightがundefinedとなっていることが分かりました。

    // set the width and height parameters
    let width = dimensionMatch[1];
    let height = dimensionMatch[2];

↑よくよく見てみると、ここの添字が1と2になっていました。

ちなみに原文(左)では直っていました。↓
スクリーンショット 2019-12-27 15.05.02.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0