最新消息:

一键转贴Chrome扩展开发经验总结3:怎样判断任意链接是否为图片类型

技术 admin 2612浏览 0评论

问题

在一键转贴开发中,首先面临两个基本问题:
问题1:任意给定一个URL链接地址,怎样判断链接对应的资源是否为图片呢?

问题2:如果是图片,怎样获取图片的width、height、图片类型(JPEG、PNG、GIF、WEBP等)等元信息meta info。延展开来,如果图片类型了为WEBP,还需要判断WEBP类型的图片是否为动画图片(GIF、APNG)。

这两个基本问题,貌似简单,但实际上还有点复杂。按照最直观的方案处理,都存在问题。

对于问题1,最直接了当的方案是根据URL地址中,是否包含图片后缀.jpg、.jpeg等,此种方案极为不靠谱。很多网站图片URL地址并不包含.jpg等代表图片类型的信息。另外由于文件后缀只是约定俗成,并不能限制用户修改后缀,根据文件名后缀来判断文件类型也不准确。

对于问题2最直接了当的方案是查询 imge的width、height属性,只不过width、height只是用于设定浏览器端显示的尺寸,并不是图片实际尺寸。使用naturalWidth和naturalHeight在此种场景下也不适用。例如,如果链接地址就是图片地址,没有img标签,唯一信息就是图片二进制流,也即:怎样从二进制流中提取图片的width、height等meta info?

解决方案

在《下载文件 MIME TYPE智能检测》中谈到了通过XMLHttpRequest(XHR)+ DataView + ArrayBuffer可以得到图片的mime type。只不过在那篇文中,基本上假定传入链接为图片,并未对传入的任意链接做处理。

大致思路:
沿用《下载文件 MIME TYPE智能检测》的思路,用XMLHttpRequest(XHR)请求传入的任意地址,xhr.responseType=”arraybuffer”。然后对response的arrayBuffer先判断是否为图片类型,如果不是,将arrayBuffer转为text,对text内容进一步处理。

data = new TextDecoder("utf-8").decode(new Uint8Array(arrayBuffer));

之所以要将arrayBuffer转为text,一方面要排除服务器端直接返回以data:image/jpeg;base64 形式存储的图片,另外也方便对文本内容做进一步处理。

备注:最初以为可以直接通过判断arrayBuffer.byteLength来区分图片和普通网页内容,后来发现不行。

要将处理逻辑,封装成函数isImage(url)供对外调用,发现在xhr.onload中 return中无法正常返回值。

问题原因:XMLHttpRequest 为异步请求asynchronous,而return 为 synchronous,必须使用callback或Promise。

开发一键转贴的最大收获之一就是对Promise及async/await的结合使用有了深刻的理解。

 

关于问题2,对图片元数据的获取,后面文章继续阐述。

转载请注明:出家如初,成佛有余 » 一键转贴Chrome扩展开发经验总结3:怎样判断任意链接是否为图片类型

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址