fix: 图片编辑器上传图片先传服务器获取URL,彻底禁止base64

This commit is contained in:
Your Name 2026-02-03 14:39:10 +08:00
parent 98bc457082
commit e24d2cf9b0

View File

@ -78,8 +78,23 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod
const fileInputRef = useRef<HTMLInputElement>(null);
// 处理拖拽上传
const handleDrop = useCallback((e: React.DragEvent<HTMLDivElement>) => {
// 上传图片到服务器获取 URL 的辅助函数
const uploadImageFile = async (file: File): Promise<string> => {
const formData = new FormData();
formData.append("file", file);
const response = await fetch("/api/files/upload", {
method: "POST",
body: formData,
});
if (!response.ok) {
throw new Error("上传失败");
}
const result = await response.json();
return result.url;
};
// 处理拖拽上传 - 先上传到服务器获取URL
const handleDrop = useCallback(async (e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
e.stopPropagation();
@ -94,11 +109,13 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod
toast.error("图片大小不能超过 10MB");
return;
}
const reader = new FileReader();
reader.onload = (e) => {
const result = e.target?.result as string;
setOriginalImageUrl(result);
try {
setIsLoading(true);
toast.info("正在上传图片...");
const imageUrl = await uploadImageFile(file);
setOriginalImageUrl(imageUrl);
setProcessedImageUrl(null);
setProcessedImageBase64(null);
setProcessType(null);
@ -106,9 +123,22 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod
setCurrentAction(null);
const img = new window.Image();
img.src = result;
};
reader.readAsDataURL(file);
img.crossOrigin = "anonymous";
img.onload = () => {
setImage(img);
setIsLoading(false);
};
img.onerror = () => {
setIsLoading(false);
toast.error("图片加载失败");
};
img.src = imageUrl;
toast.success("图片上传成功");
} catch (error) {
console.error("上传图片失败:", error);
toast.error("上传失败,请重试");
setIsLoading(false);
}
}
}, []);
@ -117,11 +147,11 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod
e.stopPropagation();
}, []);
// 处理粘贴上传
// 处理粘贴上传 - 先上传到服务器获取URL
useEffect(() => {
if (!mounted || originalImageUrl) return;
const handlePaste = (e: ClipboardEvent) => {
const handlePaste = async (e: ClipboardEvent) => {
const items = e.clipboardData?.items;
if (!items) return;
@ -135,11 +165,12 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod
return;
}
const reader = new FileReader();
reader.onload = (e) => {
const result = e.target?.result as string;
setOriginalImageUrl(result);
try {
setIsLoading(true);
toast.info("正在上传图片...");
const imageUrl = await uploadImageFile(file);
setOriginalImageUrl(imageUrl);
setProcessedImageUrl(null);
setProcessedImageBase64(null);
setProcessType(null);
@ -147,9 +178,22 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod
setCurrentAction(null);
const img = new window.Image();
img.src = result;
};
reader.readAsDataURL(file);
img.crossOrigin = "anonymous";
img.onload = () => {
setImage(img);
setIsLoading(false);
};
img.onerror = () => {
setIsLoading(false);
toast.error("图片加载失败");
};
img.src = imageUrl;
toast.success("图片上传成功");
} catch (error) {
console.error("上传图片失败:", error);
toast.error("上传失败,请重试");
setIsLoading(false);
}
break;
}
}
@ -255,19 +299,22 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod
});
}, []);
// 处理本地图片上传
const handleImageUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
// 处理本地图片上传 - 先上传到服务器获取URL
const handleImageUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (file) {
if (file.size > 10 * 1024 * 1024) {
toast.error("图片大小不能超过 10MB");
e.target.value = "";
return;
}
const reader = new FileReader();
reader.onload = (e) => {
const result = e.target?.result as string;
setOriginalImageUrl(result);
try {
setIsLoading(true);
toast.info("正在上传图片...");
const imageUrl = await uploadImageFile(file);
setOriginalImageUrl(imageUrl);
// 重置状态
setProcessedImageUrl(null);
setProcessedImageBase64(null);
@ -282,9 +329,17 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod
setImage(img);
setIsLoading(false);
};
img.src = result;
};
reader.readAsDataURL(file);
img.onerror = () => {
setIsLoading(false);
toast.error("图片加载失败");
};
img.src = imageUrl;
toast.success("图片上传成功");
} catch (error) {
console.error("上传图片失败:", error);
toast.error("上传失败,请重试");
setIsLoading(false);
}
}
// 重置 input
e.target.value = "";