当前位置: 首页 > wzjs >正文

网站建设对企业影响有多大关键词林俊杰无损下载

网站建设对企业影响有多大,关键词林俊杰无损下载,东莞网站建设 信科网络,wordpress分页怎样调用前言 与阿里的oss不同的是S3不支持通过url参数实现这种类似黑盒的图片处理,而是提供了一种特殊的lambda函数,我虽然不清楚为什么叫做lambda函数,但其本质就是一个拦截器。下面就演示一下利用lambda函数实现图片缩放和质量转换。 cloudfront是…

前言

  • 与阿里的oss不同的是S3不支持通过url参数实现这种类似黑盒的图片处理,而是提供了一种特殊的lambda函数,我虽然不清楚为什么叫做lambda函数,但其本质就是一个拦截器。下面就演示一下利用lambda函数实现图片缩放和质量转换。

  • cloudfront是什么?这个是一个缓存服务,就是经常听说的cdn

  • 有四个阶段可以做图片处理,下文选择的是在origin request事件中做图片处理。
    在这里插入图片描述

有几个前置步骤,这里只列出,不做细致演示。

  • aws账号注册,注册后需要绑定一张信用卡才能使用。新注册用户有12个月的免费资源使用。从绑定银行卡之日起计算。
  • 创建存储桶,这个和阿里OSS一样。

创建桶之后注意需要修改访问权限,否则访问不到。
在这里插入图片描述

步骤一:配置cloudfront(cdn)

  • 创建地址:https://us-east-1.console.aws.amazon.com/cloudfront/v4/home?region=us-east-1#/distributions
  • 注意cloudfront必须配置在佛吉尼亚北部
    在这里插入图片描述
    在这里插入图片描述
    这里需要注意一下, 启用了防火墙之后价格是按照请求另外计算的,防火墙不在免费资源范围内
    在这里插入图片描述
    创建完成之后,回到首页
    在这里插入图片描述
    点进去之后,这里就可以看到域名了。尝试使用该域名访问:https://图片中的域名/resized-boke.jpg
    在这里插入图片描述
    现在cloudfront就基本配置完成了。

步骤二: 创建lmabda edge函数

  • 创建地址:https://us-east-1.console.aws.amazon.com/lambda/home?region=us-east-1#/discover
    在这里插入图片描述
    创建函数时注意选择蓝图(这个一看就是机器翻译的,其实就是模板的意思)。执行角色这个不管选择哪个,后面都要去配置一下角色权限(https://us-east-1.console.aws.amazon.com/iam/home?region=us-east-1#/roles),防止出现执行函数异常的问题,或者日志不打印的问题。
    在这里插入图片描述
    注意一路向下部署完成后,此时版本1已经生效,回到函数页面点击更新函数,编写代码。
    在这里插入图片描述

步骤三:编写lambda函数代码:

import {GetObjectCommand, S3Client} from '@aws-sdk/client-s3';
import sharp from 'sharp';
import {Buffer} from 'buffer';
import {Readable} from 'stream';
import {parse} from 'querystring';const bucketName = 'chengzhi-test-resized';/*** 多个处理参数使用&符号分隔: /test.png@resize=50x50&width=50&height=50&proportion=50&quality=50* 图片处理参数类型:* - 按照像素缩放:    @resize=50x50* - 按照宽度等比缩放: @width=20* - 按照高度等比缩放: @height=200* - 按照比例缩放:    @proportion=99* - 质量转换:       @quality=50* @param event* @param context* @returns*/
export const handler = async (event, context) => {const cf = event.Records[0].cf;const request = cf.request;const params = getParams(request.uri);if (params === undefined) {console.log("未携带处理参数,不进行处理!");} else {let response = '';const image = params.image;const objectKey = `${image}`;const trigger_point = cf.response ? 'RESPONSE' : 'REQUEST';if (trigger_point === 'REQUEST') {let buffer = await getObjectBuffer(bucketName, objectKey);if (buffer === undefined) {return request;}if (params.resize) {buffer = await resizeImage(buffer, params.resize);}if (params.width) {buffer = await widthImage(buffer, params.width);}if (params.height) {buffer = await heightImage(buffer, params.height);}if (params.proportion) {buffer = await proportionImage(buffer, params.proportion);}if (params.quality) {buffer = await qualityImage(buffer, image.split('.')[1],params.quality);}return generateResponse(response, buffer, trigger_point);}}return request;
};async function getObjectBuffer(bucket_name, objectKey) {const region = "eu-north-1";const s3 = new S3Client({region: region});try {const params = {Bucket: bucket_name,Key: objectKey};var response = await s3.send(new GetObjectCommand(params));var stream = response.Body;if (stream instanceof Readable) {var content_buffer = Buffer.concat(await stream.toArray());return content_buffer;} else {throw new Error('Unknown object stream type');}} catch (error) {console.log(error);return;}
}async function heightImage(content_buffer, height) {try {let pipeline = sharp(content_buffer);height = Number(height);let resizeConfig = {height: height};pipeline = pipeline.resize(resizeConfig);return await pipeline.toBuffer();} catch (error) {console.log(error);return;}
}
async function widthImage(content_buffer, width) {try {let pipeline = sharp(content_buffer);width = Number(width);let resizeConfig = {width: width};pipeline = pipeline.resize(resizeConfig);return await pipeline.toBuffer();} catch (error) {console.log(error);}
}
/*** 等比例缩放图片* @param content_buffer* @param proportion       百分比(0-100)* @returns {Promise<*>}*/
async function proportionImage(content_buffer, proportion) {try {let pipeline = sharp(content_buffer);const metadata = await pipeline.metadata();proportion = Number(proportion);const percentage = proportion / 100;let resizeConfig = {width: Math.round(metadata.width * percentage)};pipeline = pipeline.resize(resizeConfig);return await pipeline.toBuffer();} catch (error) {console.log(error);}
}
/*** 裁剪图片* @param content_buffer* @param size            例如:50x40* @returns {Promise<*>}*/
async function resizeImage(content_buffer, size) {try {const [width, height] = size.split('x').map(Number);var output_buffer = await sharp(content_buffer).resize(width,height).toBuffer();} catch (error) {console.log(error);return;}return output_buffer;
}/*** 图片质量转换* @param content_buffer* @param format            图片格式* @param quality           目标质量(0-100)* @returns {Promise<*>}*/
async function qualityImage(content_buffer, format, quality) {try {// 传入的quality为字符串quality = Number(quality);console.log('quality:', quality)console.log('format:', format)let pipeline = sharp(content_buffer);// 根据格式设置质量switch (format.toLowerCase()) {case 'jpeg':case 'jpg':pipeline = pipeline.jpeg({quality: quality,mozjpeg: true  // 使用 mozjpeg 优化});break;case 'png':pipeline = pipeline.png({quality: quality,compressionLevel: 9  // PNG 压缩级别 0-9});break;case 'webp':pipeline = pipeline.webp({quality: quality,lossless: false  // 有损压缩});break;case 'avif':pipeline = pipeline.avif({quality: quality,lossless: false});break;}console.log('质量转换完成!')var outputBuffer = await pipeline.toBuffer();console.log('流转换完成!')} catch (error) {console.log(error);return;}return outputBuffer;
}
function generateResponse(response, buffer, trigger_point) {if (trigger_point === 'REQUEST') {response = {status: '',statusDescription: '',headers: {'cache-control': [{key: 'Cache-Control',value: 'max-age=100'}],'content-type': [{key: 'Content-Type',value: 'image/png'}],'content-encoding': [{key: 'Content-Encoding',value: 'base64'}]},body: '',bodyEncoding: 'base64'};}response.status = '200';response.body = buffer.toString('base64');response.bodyEncoding = 'base64';response.headers['content-type'] = [{key: 'Content-Type',value: 'image/png'}];response.headers['content-encoding'] = [{key: 'Content-Encoding',value: 'base64'}];response.statusDescription = trigger_point === 'REQUEST'? 'Generated by CloudFront Original Request Function': 'Generated by CloudFront Original Response Function';return response;
}function getParams(image) {image  = image.startsWith('/') ? image.slice(1) : imageif (!image.includes('@')) {console.log("不包含@符号,不需要进行处理!");return;}var strings = image.split('@');if (strings.length < 2) {console.log("@符号位置不正确,不进行处理");return;}var result = parse(strings[1]);var picture = strings[0];if (picture === undefined || !picture.match(/\.(jpg|jpeg|png|gif|webp)$/i)) {console.log("非图片类,不进行处理");return;}if (result !== undefined) {result.image = picture;}console.log("图片处理参数:", JSON.stringify(result))return result;
}

函数编写完成后,需要将依赖打包,注意因为是要在aws的服务器上运行该代码,所以引入的依赖必须是linux版本的。以下是代码中使用到的两个依赖。

npm install --arch=x64 --platform=linux --target=16x sharp@0.32.6
npm install --arch=x64 --platform=linux --target=16x aws-sdk@2.1450.0 

依赖引入完成后,需要打包成zip包,包结构如图,如果zip包超过10M,上传会超时,需要使用S3上传,注意上传代码的S3也必须是弗吉尼亚北部。否则上传会失败。
在这里插入图片描述

代码上传完成后,一定要修改函数执行超时时间,否则函数运行1s后,就自动停止了。

在这里插入图片描述

步骤四:部署

代码完成后,点击添加触发器,选择cloudfront(注意如果函数不是在弗吉尼亚北部,这个是选择不到的),按照提示填写配置。注意我上面的代码cluodfront事件选择的是源请求
在这里插入图片描述

步骤五: 测试

https://域名/novel1.png@height=200
在这里插入图片描述
验证是否生成缓存
https://us-east-1.console.aws.amazon.com/cloudfront/v3/home?region=us-east-1#/popular_urls
在这里插入图片描述

查看日志

查看日志的时候需要注意右上角的地区,由于lambda函数是部署在cloudfront上的,而cloudfront是全球分布多个节点,一般本地访问都是优先连接附近的节点,因此日志也会出现在附近的地区节点上,比如,我在上海访问,那么日志会随机落到东京孟买。如果IAM角色权限未正确配置(https://us-east-1.console.aws.amazon.com/iam/home?region=us-east-1#/roles),不会打印日志。
在这里插入图片描述

答疑

  • 1、为什么要在url中使用@?
    答: 在测试过程中发现,函数中无法获取到queryString的参数,也就是说无法获取到url问号后面的参数部分,因此采用@然后在程序中做分割处理,这样一来可以解决获取参数的问题, 二来可以解决图片名称相同但尺寸不同的缓存问题。

  • 2、为什么要在源请求中做处理?
    答: 刚开始也考虑在源响应中做处理,但是发现源响应的response中并没有body,咨询了aws的售前说源响应是没有body的。
    在这里插入图片描述

  • 3、是否可以兼容ali oss图片处理参数?
    答:基于上述内容可以发现,lambda函数使用的是sharp库,这个库中支持的那大概率都能实现,我只是因为只需要用到这几个处理方式。

  • 4、为什么使用Node,不适用python?
    答: 刚开始尝试使用了python,但是打包上传到服务上时提示,有包冲突,谷歌了一下,说是需要用到aws的一个,个人觉比较复杂,就更换了node.

参考文档:

https://aws.amazon.com/cn/blogs/china/use-cloudfront-lambdaedge-for-transaction-processing/
https://docs.aws.amazon.com/zh_cn/lambda/latest/dg/getting-started.html#get-started-invoke-manually
https://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/lambda-at-the-edge.html
https://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.SimpleDistribution.html
https://docs.aws.amazon.com/zh_cn/lambda/latest/dg/with-s3-tutorial.html
https://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/popular-objects-report.html

http://www.dtcms.com/wzjs/499980.html

相关文章:

  • 和县网站建设重庆seo网页优化
  • 百度推广长春分公司外包优化网站
  • 大学校园门户网站建设方案重庆网站建设软件
  • 查注册公司什么网站长沙关键词排名软件
  • 网站空间ip需不需要备案毛戈平化妆培训学校官网
  • 自己做的网站怎么收藏本站免费招聘信息发布平台
  • 单位网站党风廉政建设图片怎样推广自己的广告
  • 做企业网站用php百度云搜索引擎官网入口
  • 做网站卖广告多少钱百度搜首页
  • 取消网站验证码怎样无货源开网店
  • 关键词优化除了做网站还有什么方法百度广告点击软件源码
  • 盘锦建设信息网站安徽疫情最新情况
  • WordPress首页怎么打开seo搜索引擎优化推广专员
  • 个人博客网页模板图片seo推广人员
  • 厦门专业网站建设建站怎么样做seo
  • wamp建设网站大致步骤百度seo关键词优化推荐
  • dede做网站地图如何优化搜索关键词
  • 电商网站建设设计报告总结网站搭建谷歌seo
  • 如何查询网站的访问量seo自然优化排名
  • 网站空间怎么收费郑州seo地址
  • 网络培训课堂seo首页排名优化
  • 杭州 建设网站手机百度云网页版登录
  • 怎么验证网站备案密码是否正确网络运营课程培训班
  • 建设银行网站 诚聘英才 频道如何注册网站
  • 西安网站开发公司哪家强长沙网站seo优化公司
  • 网站底部公司是什么样的免费网站或软件
  • 怎么筛选一家做网站做的好的公司站长之家app下载
  • 网站和微信公众号建设方案百度云官网首页
  • 做ppt找图片的网站有哪些今日要闻10条
  • 公司建设网站申请报告seo网站建设是什么意思