最近两天老师给布置了一个小任务. 有一个页面用到了 UEditor 文本编辑器, 用户经常会直接粘贴整篇文档到编辑区, 包括很多图片. 图片的来源都是粘贴来源的地址, 这可能大大影响图片的加载效率, 以及如果源地址删除该图片, 文章也无法正常显示. 我要做的就是从该文章中, 提取所有的图片, 保存到七牛云存储. 这样, 每次显示文章, 就能直接从自己的云存储加载图片.
首先, 我的大概思路是: 获取正片文章内容, 正则匹配出所有的 img 标签, 然后再匹配出每个 img 标签的 src 属性值, 也就是获得了每张图片的源地址. 本来不了解七牛云, 所以在如何上传到七牛云上卡住了. 刚好到了周末, 就趁着这两天时间, 大概过了一下七牛 api 文档, 了解到了 fetch 接口进行远程资源抓取.
以下上代码:
1. 获取所有图片的源地址
- // 匹配出所有的 img 标签
- const imgPtn = /<img\b.*?(?:>|\/>)/gi;
- // 匹配出每个 img 标签中的 src 属性
- const srcPtn = /src=['"]?([^'"]*)['"]?/i;
- let images;
- if (content) {
- images = content.match(imgPtn); // 获取图片
- }
- if (images) { // 文本编辑区有图片
- images.forEach(function (list) {
- if (list.match(srcPtn)) {
- // 获取 srcs 数组, 并去除每个 src 的 " " 符号
- srcs.push(list.match(srcPtn)[0].split('=')[1].slice(1, -1));
- }
- }
个人需要, 对 srcs 进行过滤, 获得指定域名的来源的图片 src.
2. 进行远程抓取
- function fetchImg(url, bucket, key, callback) {
- qiniu.conf.ACCESS_KEY = "自己的 accesskey";
- qiniu.conf.SECRET_KEY = "自己的 secretkey" ;
- const client = new qiniu.rs.Client();
- key = `/images/ ${md5(new Date().getTime())}`; // 可以自己定义 key 的前缀
- client.fetch(url, bucket, key, function (err, ret) {
- if (err) {
- console.log(err);
- } else {
- console.log(ret);
- }
- });
可以看到, key 值我是自定义的 images / 图片名. 这主要使用 md5 对当前时间进行 hash, 保证图片命名的唯一性.
但有一缺点就是: 如果 key 传参为空的时候, 七牛会自定义生成 key, 而且上传同一张图片的时候, 将会覆盖, 也就说不会存在完全相同的两张图片.
如果自定义 key 值, 就要保证图片命名的唯一性, 而以上办法, 虽然做到了这点, 但无法对同一张图片进行覆盖上传.
因为对 time 进行 hash, 基本不会得到完全相同的图片名.
- // 通过 fetch 进行远程图片抓取, qiniu.rs 中有对应的 api
- fetchImg(url, bucket, '', callback);
调用的时候 key 传参位空.
来源: https://blog.csdn.net/yinkaihui/article/details/52085640