V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
panisertoller
V2EX  ›  问与答

腾讯云边缘安全加速(EdgeOne)之图片优化

  •  
  •   panisertoller · 319 天前 · 492 次点击
    这是一个创建于 319 天前的主题,其中的信息可能已经有所发展或是发生改变。

    应用背景

    前面已经介绍过 EdgeOne 的基本使用方法(参见 腾讯云下一代 CDN ( EdgeOne/边缘安全加速)开箱即用 一文),本文将介绍如何使用 EdgeOne Worker 实现图片格式转换。

    通过云边缘函数实现自动优化图片格式,可以提升页面加载速度,优化图片加速性能,进而提高网站的用户体验。

    产品简介

    腾讯云边缘函数( Edge Functions )提供了 EdgeOne 边缘节点的 Serverless 代码执行环境,只需编写业务函数代码并设置触发规则,无需配置和管理服务器等基础设施,即可在靠近用户的边缘节点上弹性、安全地运行代码。

    目前该功能已公测上线,个人版优惠后仅 9.9 元/月,最近一段时间用下来,感觉还是方便的,尤其是处理图片缩放和格式转化的时候,使用免费的边缘函数来实现,香飘四野啊~~

    套餐信息请查阅产品购买地址

    实现步骤

    官方最佳实践示例代码通过判断浏览器类型来设置转化格式,但是判断逻辑过于简单,容易产生误判导致返回不支持的编码格式。本文通过获取请求头中的 Accept 信息,来识别浏览器支持的图片类型,并使用 fetch API 获取源站图片,根据浏览器支持的图片编码类型对图片进行格式转换,以实现图片自适应格式的效果。

    5.png

    • 验证函数是否按照预期运行,您可通过在浏览器或 Curl 发起请求测验,查看返回的头信息是否包含Backend-Option,以及其值是否为{"eo":{"image":{"format":"avif"}}}{"eo":{"image":{"format":"webp"}}}。若包含且值正确,则表示函数已按照预期运行

    6.png

    边缘函数代码

    /**
     * 图片转换 for EdgeOne Worker
     * @url https://www.rehiy.com/post/505/
     * @author Rehiy
     */
    
    async function handleEvent(request) {
        const uObj = new URL(request.url);
        const resize = uObj.search.match(/(\d+)x(\d+)/);
        const accept = request.headers.get('Accept');
    
        const option = {
            eo: {
                image: {},
                cacheKey: request.url,
            }
        };
    
        if (resize) {
            if (resize[1] > 0) {
                option.eo.image.width = +resize[1];
            }
            if (resize[2] > 0) {
                option.eo.image.height = +resize[2];
            }
        }
    
        for (const format of ['avif', 'webp', 'jp2', 'jxr', 'heif']) {
            if (accept.includes(format)) {
                option.eo.image.format = format;
                option.eo.cacheKey += '.' + format;
                break;
            }
        }
    
        const resp = await fetch(request, option);
        resp.headers.set('Backend-Option', JSON.stringify(option));
        resp.headers.set('Vary', 'Accept');
    
        return resp;
    }
    
    // eo listener
    
    addEventListener('fetch', event => {
        event.passThroughOnException();
        event.respondWith(handleEvent(event.request));
    });
    
    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5045 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 05:54 · PVG 13:54 · LAX 22:54 · JFK 01:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.