fix(upload): 恢复并增强Base64前端逻辑,绕过服务器网络访问限制

This commit is contained in:
hangyu.tao 2026-02-02 11:30:06 +08:00
parent a2ad9cafde
commit 7964ccd062
2 changed files with 69 additions and 45 deletions

View File

@ -1180,7 +1180,7 @@
</div> </div>
<!-- Scripts --> <!-- Scripts -->
<script src="/static/js/main.js?v=4.0"></script> <script src="/static/js/main.js?v=5.0"></script>
<script src="/static/js/trial-periods.js?v=1.3"></script> <script src="/static/js/trial-periods.js?v=1.3"></script>
<script src="/static/js/trial-periods-page.js?v=1.6"></script> <script src="/static/js/trial-periods-page.js?v=1.6"></script>
</body> </body>

View File

@ -61,7 +61,7 @@ function canDelete() {
} }
document.addEventListener("DOMContentLoaded", function () { document.addEventListener("DOMContentLoaded", function () {
console.log("CRM System Main JS v4.5 Loaded - " + new Date().toLocaleString()); console.log("CRM System Main JS v5.0 Loaded - " + new Date().toLocaleString());
// 登录守卫 // 登录守卫
const token = localStorage.getItem("crmToken"); const token = localStorage.getItem("crmToken");
if (!token && !window.location.pathname.endsWith("login.html")) { if (!token && !window.location.pathname.endsWith("login.html")) {
@ -3233,54 +3233,78 @@ document.addEventListener("DOMContentLoaded", function () {
const files = Array.from(this.files); const files = Array.from(this.files);
if (files.length === 0) return; if (files.length === 0) return;
const formData = new FormData(); const newBase64Images = [];
files.forEach(file => {
if (file.type.startsWith("image/")) {
formData.append("screenshots", file);
} else {
console.warn(`File is not an image: ${file.name}`);
}
});
if (formData.getAll("screenshots").length === 0) { // Helper to convert file to base64 with retry
alert("请选择有效的图片文件"); const fileToBase64 = async (f, attempt = 1) => {
return; try {
return await new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = () => reject(reader.error || new Error("FileReader error"));
reader.onabort = () => reject(new Error("File read aborted"));
reader.readAsDataURL(f);
});
} catch (err) {
// If NotReadableError, retry up to 3 times
if (attempt < 3 && (err.name === "NotReadableError" || err.code === 1)) {
console.warn(`Retrying ${f.name} read due to error (attempt ${attempt})...`);
await new Promise(r => setTimeout(r, 200 * attempt));
return fileToBase64(f, attempt + 1);
}
throw err;
}
};
for (const file of files) {
if (!file.type.startsWith("image/")) {
console.warn(`File is not an image: ${file.name}`);
continue;
}
try {
console.log(`[v5.0] Converting ${file.name} (${file.size} bytes)...`);
const base64 = await fileToBase64(file);
newBase64Images.push(base64);
console.log(`Successfully converted ${file.name}`);
} catch (error) {
console.error(`Primary method failed for ${file.name}:`, error);
// Fallback: arrayBuffer (usually works when FileReader fails)
try {
console.log(`Trying arrayBuffer fallback for ${file.name}...`);
const buffer = await file.arrayBuffer();
const bytes = new Uint8Array(buffer);
let binary = "";
const chunkSize = 8192;
for (let i = 0; i < bytes.length; i += chunkSize) {
const chunk = bytes.slice(i, i + chunkSize);
binary += String.fromCharCode.apply(null, chunk);
}
const b64 = `data:${file.type};base64,${btoa(binary)}`;
newBase64Images.push(b64);
console.log(`Fallback successful for ${file.name}`);
} catch (fallbackError) {
console.error(`Both methods failed for ${file.name}:`, fallbackError);
alert(`无法读取文件 "${file.name}"。\n这种情况通常是浏览器或系统文件锁定导致的。\n\n建议尝试:\n1. 刷新页面后再试\n2. 使用浏览器的“无痕模式”\n3. 确认文件没有被其他软件打开`);
}
}
} }
try { if (newBase64Images.length > 0) {
console.log(`[v4.0] Uploading ${files.length} files to server...`); if (type === "create") {
const response = await authenticatedFetch("/api/upload", { createUploadedScreenshots = [
method: "POST", ...createUploadedScreenshots,
body: formData, ...newBase64Images,
// Note: When sending FormData, the browser automatically sets the correct Content-Type with boundary ];
}); renderScreenshotPreviews("create", createUploadedScreenshots);
if (response.ok) {
const result = await response.json();
const newBase64Images = result.filePaths || [];
console.log(`Successfully uploaded ${newBase64Images.length} images`);
if (type === "create") {
createUploadedScreenshots = [
...createUploadedScreenshots,
...newBase64Images,
];
renderScreenshotPreviews("create", createUploadedScreenshots);
} else {
editUploadedScreenshots = [
...editUploadedScreenshots,
...newBase64Images,
];
renderScreenshotPreviews("edit", editUploadedScreenshots);
}
} else { } else {
const errorText = await response.text(); editUploadedScreenshots = [
console.error("Upload failed:", errorText); ...editUploadedScreenshots,
alert("图片上传失败,请稍后重试。"); ...newBase64Images,
];
renderScreenshotPreviews("edit", editUploadedScreenshots);
} }
} catch (error) {
console.error("Error during upload:", error);
alert("上传过程出错,可能是浏览器权限问题或网络连接中断。");
} }
// 清除 input以便再次选择同一张图片 // 清除 input以便再次选择同一张图片