如何在Cloudflare Workers中获取图片尺寸?解决Image未定义报错
解决Cloudflare Worker中无法使用Image/createImageBitmap获取图片宽高的问题
问题原因
Cloudflare Worker运行在无DOM的V8隔离环境中,Image、createImageBitmap这类浏览器专属的DOM API并不存在,直接调用会抛出ReferenceError。获取图片宽高无需渲染图片,解析图片文件的元数据即可实现。
解决方案1:纯JS解析图片文件头(无外部依赖)
通过读取图片的ArrayBuffer,解析PNG、JPEG等常见格式的文件头元数据获取宽高,适合轻量场景:
addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) async function handleRequest(request) { const imageUrl = new URL(request.url).searchParams.get('imageUrl') if (!imageUrl) { return new Response(JSON.stringify({ error: '缺少imageUrl参数' }), { headers: { 'content-type': 'application/json' }, status: 400 }) } try { const response = await fetch(imageUrl) const arrayBuffer = await response.arrayBuffer() const { width, height } = getImageDimensions(arrayBuffer) return new Response(JSON.stringify({ width, height }), { headers: { 'content-type': 'application/json' } }) } catch (err) { return new Response(JSON.stringify({ error: err.message }), { headers: { 'content-type': 'application/json' }, status: 500 }) } } function getImageDimensions(arrayBuffer) { const view = new DataView(arrayBuffer) // 检测PNG格式 if (view.getUint8(0) === 0x89 && view.getUint8(1) === 0x50 && view.getUint8(2) === 0x4E && view.getUint8(3) === 0x47) { return { width: view.getUint32(16, false), height: view.getUint32(20, false) } } // 检测JPEG格式 if (view.getUint8(0) === 0xFF && view.getUint8(1) === 0xD8) { let offset = 2 while (offset < view.byteLength) { if (view.getUint8(offset) !== 0xFF) break const marker = view.getUint8(offset + 1) // 匹配包含尺寸信息的JPEG标记段 if ((marker >= 0xC0 && marker <= 0xC3) || (marker >= 0xC5 && marker <= 0xC7) || (marker >= 0xC9 && marker <= 0xCB) || (marker >= 0xCD && marker <= 0xCF)) { return { height: view.getUint16(offset + 5, false), width: view.getUint16(offset + 7, false) } } const segmentLength = view.getUint16(offset + 2, false) offset += segmentLength + 2 } } throw new Error('不支持的图片格式或解析失败') }
解决方案2:使用第三方库(支持更多格式)
如果需要支持WebP、GIF等更多格式,可使用image-size库,它能纯JS解析多种图片的元数据:
- 初始化项目并安装依赖:
npm init -y npm install image-size
- 修改代码为ES模块形式:
import sizeOf from 'image-size' addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) async function handleRequest(request) { const imageUrl = new URL(request.url).searchParams.get('imageUrl') if (!imageUrl) { return new Response(JSON.stringify({ error: '缺少imageUrl参数' }), { headers: { 'content-type': 'application/json' }, status: 400 }) } try { const response = await fetch(imageUrl) const arrayBuffer = await response.arrayBuffer() const dimensions = sizeOf(arrayBuffer) return new Response(JSON.stringify({ width: dimensions.width, height: dimensions.height }), { headers: { 'content-type': 'application/json' } }) } catch (err) { return new Response(JSON.stringify({ error: err.message }), { headers: { 'content-type': 'application/json' }, status: 500 }) } }
- 用
wrangler工具打包部署即可,Cloudflare Worker支持该库的ES模块导入。
内容的提问来源于stack exchange,提问作者Marcel
相关产品推荐
相关产品推荐

