适合个人用的前端下载图片跨域解决方案
Sonder
7天前
2946字
7分钟
浏览 (56)
/**
* 图片下载器类 - 保持原图下载
*/
class ImageDownloader {
/**
* @param {Object} options - 配置选项
* @param {string} options.proxyUrl - 代理服务器URL(可选)
*/
constructor(options = {}) {
this.image = new Image();
this.proxyUrl =
options.proxyUrl || "https://api.codetabs.com/v1/proxy?quest=";
this.canvas = document.createElement("canvas");
this.ctx = this.canvas.getContext("2d");
}
/**
* 加载图片
* @param {string} url - 图片URL
* @returns {Promise} - 返回Promise
*/
loadImage(url) {
return new Promise((resolve, reject) => {
this.image.crossOrigin = "anonymous";
this.image.onload = () => {
// 设置canvas尺寸为图片原始尺寸
this.canvas.width = this.image.width;
this.canvas.height = this.image.height;
resolve(this.image);
};
this.image.onerror = () => reject(new Error("图片加载失败"));
// 如果提供了代理URL,则使用代理
const imageUrl = this.proxyUrl
? `${this.proxyUrl}${encodeURIComponent(url)}`
: url;
// 添加时间戳防止缓存
this.image.src = `${imageUrl}${imageUrl.includes("?") ? "&" : "?"}t=${Date.now()}`;
});
}
/**
* 在画布上绘制原始尺寸的图片
*/
drawImage() {
// 清空画布并填充白色背景
this.ctx.beginPath();
this.ctx.rect(0, 0, this.canvas.width, this.canvas.height);
this.ctx.fillStyle = "white";
this.ctx.fill();
// 绘制原始尺寸的图片
this.ctx.drawImage(this.image, 0, 0);
}
/**
* 下载画布上的图片
* @param {string} filename - 文件名
* @param {Object} options - 下载选项
* @param {string} options.type - 图片类型,默认 'image/jpeg'
* @param {number} options.quality - 图片质量,0-1之间,默认1.0保持最佳质量
*/
downloadImage(filename, options = {}) {
const { type = "image/jpeg", quality = 1.0 } = options;
const link = document.createElement("a");
link.download = filename || "image.jpg";
link.href = this.canvas.toDataURL(type, quality);
// 创建并触发点击事件
const event = new MouseEvent("click", {
view: window,
bubbles: true,
cancelable: true
});
link.dispatchEvent(event);
}
/**
* 加载并下载原始图片的便捷方法
* @param {string} url - 图片URL
* @param {string} filename - 保存的文件名
* @param {Object} options - 下载选项
* @returns {Promise}
*/
async loadAndDownload(url, filename, options = {}) {
try {
await this.loadImage(url);
this.drawImage();
this.downloadImage(filename, options);
return true;
} catch (error) {
console.error("下载图片失败:", error);
throw error;
}
}
}
// 使用示例:
/*
const downloader = new ImageDownloader({
proxyUrl: 'https://api.codetabs.com/v1/proxy?quest=' // 可选的代理服务
});
// 使用方式:
downloader.loadAndDownload(
'https://example.com/image.jpg',
'original-image.jpg',
{
type: 'image/jpeg',
quality: 1.0 // 使用最高质量
}
).catch(console.error);
*/
export default ImageDownloader;