通过AWS CloudFront的function解决S3静态站点的trailing slash redirect的参数问题

在AWS中,可以通过CloudFront把S3的静态站点作为一个Origin,对外提供服务。这种方式可以提供如下的几点便利:

  • 可以通过CloudFront的CDN服务来对静态资源进行加速
  • 如果域名通过Route 53解析,那么可以通过aws的Certificate Manager生成一个免费的SSL证书,并且可以到期时自动续期
  • 可以通过CloudFront的设置,Policy以及Edge Function等功能实现对request/response的一些定制化功能

在使用CloudFront的过程中,我们发现了一个这样一个问题。

在S3的静态站点设置中,如果访问的地址没有trailing slash,比如 https://exmaple.com/app,并且在S3的Bucket中存在对应的/app/index.html,那么S3的静态站点会自动的反馈一个302的response,将/app重定向到/app/。而如果请求的地址是带有querystring的,比如https://exmaple.com/app?from=source,那么在302中,这个querystring会被S3静态站点省略掉,于是最终跳转到的地址就会可能因为缺少必要的参数而不能正常展示或者正常tracking。

在这种情况下,我们利用了CloudFront的edge function机制,对原有request/response进行了判断和修改,在原有的302请求的基础上,增加了对于querystring的传递。

这个function可以在CloudFront的console中直接增加,实现如下:

var querystring = require('querystring');

function transformQuerystring(qs) {
    var ret = {};
    for(var k in qs) {
        var v = qs[k];
        if(!!(v.multiValue)) {
            ret[k] = Array.map(v.multiValue, function(x) {return x.value;})
        }
        else {
            ret[k] = v.value
        }
    }
    return ret;
}

function handler(event) {
    var request = event.request;
    var response = event.response;

    if(response.statusCode === 302 && !!(response.headers.location) && Object.keys(request.querystring).length > 0) {
        response.headers.location.value = response.headers.location.value
                                        + '?'
                                        + querystring.stringify(transformQuerystring(request.querystring));
    }
    return response;
}

注意,这里之所以要搞一个transformQuerystring函数,主要是因为CloudFront的Javascript环境提供了一个querystring模块,可以用于根据querystring的object重建url,但是这个object和传过来的event.request.querystring的结构并不匹配,所以需要转换一下。这个函数需要针对Viewer Response的事件类型做解析,并且在关联distribution时,需要注意Cache Behavior的设置。

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值