携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
【前端实用技巧】将网络图片下载后上传到第三方网站
引言
内容速递:看了本文您能了解到的知识
说明
在写技术文档的时候,我们写的MD文档
大多都是用的自己的OSS
。但是在发布文章的时候会发现,图片会上传到对应的平台上面,而并非是原来的MD文档
图片地址,那么,这一步是如何实现的呢?
1、通过图片链接下载图片
在网页上,我们很容易获取到图片的下载地址,具体如何获取,在这里就不具体展开了。
通过XMLHttpRequest
下载,这里下载使用Blob
格式
const downloadImg = (url) => {
return new Promise((resolve, reject) => {
// 创建请求
const xhr = new XMLHttpRequest()
xhr.open('get', url, true)
// 响应类型设置为blob
xhr.responseType = 'blob'
xhr.onload = function () {
if (this.status === 200) {
resolve(this.response)
}
}
xhr.onerror = reject
xhr.send()
})
}
复制代码
Blob 是什么?
Blob(Binary Large Object)表示二进制类型的大对象。在数据库管理系统中,将二进制数据存储为一个单一个体的集合。
Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据。File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。
测试一下
这里我使用网上的一张图片,可以看看返回的是啥

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
<script>
const url = 'https://img1.baidu.com/it/u=1966616150,2146512490&fm=253&fmt=auto&app=138&f=JPEG?w=751&h=500'
const downloadImg = (url) => {
return new Promise((resolve, reject) => {
// 创建请求
const xhr = new XMLHttpRequest()
xhr.open('get', url, true)
// 响应类型设置为blob
xhr.responseType = 'blob'
xhr.onload = function () {
if (this.status === 200) {
resolve(this.response)
}
}
xhr.onerror = reject
xhr.send()
})
}
downloadImg(url).then((res) => {
console.log(res)
})
</script>
</html>
复制代码
打印的内容:
可以看到已经成功下载到图片的Blob了
2、文件格式转化
2.1、将Blob转化为File
我们也可以将Blob
对象转为File
对象
// 将Blob对象转为File对象
const blobToFile = (blob, fileName) => {
return new window.File([blob], fileName, { type: blob.type })
}
复制代码
测试一下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
<script>
// 测试地址
const url = 'https://img1.baidu.com/it/u=1966616150,2146512490&fm=253&fmt=auto&app=138&f=JPEG?w=751&h=500'
// 下载图片
const downloadImg = (url) => {
return new Promise((resolve, reject) => {
// 创建请求
const xhr = new XMLHttpRequest()
xhr.open('get', url, true)
// 响应类型设置为blob
xhr.responseType = 'blob'
xhr.onload = function () {
if (this.status === 200) {
resolve(this.response)
}
}
xhr.onerror = reject
xhr.send()
})
}
// 将Blob对象转为File对象
const blobToFile = (blob, fileName) => {
return new window.File([blob], fileName, { type: blob.type })
}
// 测试
downloadImg(url).then((res) => {
// 获取文件名
const urlArr = url.split('/')
const fileName = urlArr[urlArr.length - 1]
console.log('Blob对象:', res)
const file = blobToFile(res, fileName)
console.log('File对象:', file)
return file
})
</script>
</html>
复制代码
打印的内容:
2.2、将Blob转为FormData
很多上传图片的,基本都是使用的FormData
格式
// 将Blob对象转为FormData对象
const blobToFormData = (blob, fileName) => {
const formData = new FormData()
formData.append('file', blob, fileName)
return formData
}
复制代码
测试一下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
<script>
// 测试地址
const url = 'https://img1.baidu.com/it/u=1966616150,2146512490&fm=253&fmt=auto&app=138&f=JPEG?w=751&h=500'
// 下载图片
const downloadImg = (url) => {
return new Promise((resolve, reject) => {
// 创建请求
const xhr = new XMLHttpRequest()
xhr.open('get', url, true)
// 响应类型设置为blob
xhr.responseType = 'blob'
xhr.onload = function () {
if (this.status === 200) {
resolve(this.response)
}
}
xhr.onerror = reject
xhr.send()
})
}
// 将Blob对象转为File对象
const blobToFile = (blob, fileName) => {
return new window.File([blob], fileName, { type: blob.type })
}
// 将Blob对象转为FormData对象
const blobToFormData = (blob, fileName) => {
const formData = new FormData()
formData.append('file', blob, fileName)
return formData
}
// 测试
downloadImg(url).then((res) => {
// 获取文件名
const urlArr = url.split('/')
const fileName = urlArr[urlArr.length - 1]
console.log('Blob对象:', res)
const file = blobToFile(res, fileName)
console.log('File对象:', file)
const formData = blobToFormData(file, fileName)
console.log('FormData对象:', formData)
return file
})
</script>
</html>
复制代码
打印内容:
然后发现打印出来的是一个空的对象,看不到效果,需要将其中的属性遍历出来
for (var key of formData.entries()) {
console.log(key[0] + ', ' + key[1]);
}
复制代码
再次打印就可以看到效果了
3、上传图片
上传图片涉及到隐私,就没有实际演示了
3.1、上传到个人网站
上传到个人网站一般使用的是FormData
的文件格式,使用的方式也有许多种
使用XMLHttpRequest
// 上传图片
const uploadImg = (formData) => {
const url = "upload_url"
let xhr = new XMLHttpRequest()
xhr.onload = function () {
console.log("上传成功")
};
xhr.onerror = function () {
console.log("上传失败")
};
xhr.open("post", url, true)
xhr.send(formData)
};
复制代码
使用Ajax
// 上传图片
const uploadImage = (formData) => {
const url = "upload_url";
$.ajax({
url,
type: "POST",
data: formData,
async: false,
cache: false,
contentType: false,
processData: false,
success: function (res) {
console.log("上传成功", res);
},
error: function (res) {
console.log("上传失败", res);
},
});
}
复制代码
使用axios
这个一般在Vue
中使用比较多
// 上传图片
const uploadImage = (formData) => {
const url = "upload_url";
axios.post(url, formData)
}
复制代码
3.2、上传到OSS
能够上传的OSS
,当然也可以上传到其他对象存储服务,可以参考OSS的案例。
在OSS
上传,可直接上传File
对象
import OSS from "ali-oss";
// 上传到OSS
export const uploadImageToOSS = async (
fileName: string,
file: File,
accessKeyId: string,
accessKeySecret: string,
...props
) => {
let client = new OSS({
endpoint,
bucket,
accessKeyId,
accessKeySecret,
internal: true,
...props,
});
const res = await client.put(fileName, file);
if (res.status === 200) {
return { url: res.url };
}
throw new Error('上传失败');
};
复制代码
总结
上传图片的场景,大部分可能用在表单上传图片、搭建自己的博客系统、配置富文本编辑器、MD文档编辑器等等。用的场景还是比较丰富。
博客说明与致谢
文章所涉及的部分资料来自互联网整理,其中包含自己个人的总结和看法,分享的目的在于共建社区和巩固自己。
引用的资料如有侵权,请联系本人删除!
感谢万能的网络,W3C,菜鸟教程等!
如果你感觉对你有帮助的话,不妨给我点赞鼓励一下,好文记得收藏哟!关注我一起成长!
幸好我在,感谢你来!