我们经常遇到这样的情况,我们填写某个表单原创内容,盗版必究。原创内容,盗版必究。的时候,需要上传一张图片,但是我们的业务转载请注明出处:www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】会有这样一个逻辑,我们这个表单会默认拉取本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。一些数据进行填充,用户在这些数据基础上进【转载请注明来源】【版权所有,侵权必究】行修改,这些拉取的数据,有的时候会使用外原创内容,盗版必究。【作者:唐霜】部数据里面的图片,此时,我们需要把外部数【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】据里面的图片保存到我们自己的服务器。这种【未经授权禁止转载】【原创内容,转载请注明出处】情况有两种解决方案,一种是纯后端做,一种【本文首发于唐霜的博客】【本文受版权保护】是前端来做。我分享一种前端来做的方案。
转载请注明出处:www.tangshuang.net【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net其实拉取数据进行填充的本质,就是不破坏我著作权归作者所有,禁止商业用途转载。【本文受版权保护】们原有的表单交互流程,前后端保持高度一致【本文首发于唐霜的博客】未经授权,禁止复制转载。,避免多态。一般的交互是提交表单的时候提【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】交上传图片,把上传后得到的文件 id 同【本文受版权保护】【转载请注明来源】表单数据一起保存。这个过程是比较顺畅的,【转载请注明来源】【未经授权禁止转载】前后端理解起来非常简单。但是,如果这里强【未经授权禁止转载】【本文首发于唐霜的博客】行改变这个逻辑,为了兼容多态,后端支持传【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】 url 字符串,实际上,这也会给前端带本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。来比较大的处理量。因此,我们的目标是,利【作者:唐霜】著作权归作者所有,禁止商业用途转载。用图片 url 转化为本地的 File 转载请注明出处:www.tangshuang.net【转载请注明来源】再提交到后端,走一个简单的流程,只不过在转载请注明出处:www.tangshuang.net【未经授权禁止转载】拉取数据这一步做一个处理。
【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net那么,怎么把外部图片转化为一个浏览器里面【版权所有,侵权必究】【原创不易,请尊重版权】的 File 呢?
原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】function getImageFile(src) {
return new Promise((resolve, reject) => {
const img = document.createElement('img');
img.style.position = 'fixed';
img.style.top = '-10000px';
img.crossOrigin = 'anonymous';
img.src = src;
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
canvas.toBlob((blob) => {
// @ts-ignore
// eslint-disable-next-line no-param-reassign
blob.lastModifiedDate = new Date();
const name = src.split('/').pop();
// @ts-ignore
// eslint-disable-next-line no-param-reassign
blob.name = name;
const file = new File([blob], name, { type: blob.type });
resolve(file);
});
document.body.removeChild(img);
};
img.onerror = (e) => {
document.body.removeChild(img);
reject(e);
};
document.body.appendChild(img);
});
}
这里用到了以下知识点:【未经授权禁止转载】
【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。- 由于是跨域的图片,所以不能直接通过 fe未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】tch 来得到 blob,于是我们利用 未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。canvas 来加载远程图片,再利用 c【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。anvas 的接口来转化数据类型 【作者:唐霜】未经授权,禁止复制转载。【本文受版权保护】【本文首发于唐霜的博客】
- canvas 要能够 draw 远程图片【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。,必须加上 crossOrigin = 本文版权归作者所有,未经授权不得转载。【转载请注明来源】anonymous 【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net
- 通过 toBlob 之后得到 blob,本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net再使用 new File([blob])【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。 就可以把 blob 转化为一个本地的文著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net件,用在提交中 【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】
- 最后需要注意,提交文件需要使用 cont原创内容,盗版必究。【未经授权禁止转载】ent-type: multipart/著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】form-data 进行提交 【本文受版权保护】【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。未经授权,禁止复制转载。【转载请注明来源】
通过这个处理,我们就可以在浏览器里面把外【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.net部图片转化为内部图片进行使用,这样就节省【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net了后端去做类似回源CDN之类的建设。
【转载请注明来源】【本文受版权保护】转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。
