Chrome多文件上传出现Uncaught TypeError错误求助
多图片上传脚本Chrome报错修复方案
问题描述
页面实现多图片上传功能,脚本在Firefox中运行正常,但在Chrome浏览器中抛出以下错误:
Uncaught TypeError: Cannot read properties of undefined (reading 'response')
at uploadComplete (UploadMultipleAlbumImages.js:79:52)

完整代码
var xhr, formData; var url = baseURL + "admin/albums/UploadImageCropAuto"; var currentLoaderRef, currentTickerRef, fileCount = 0, uploadedFiles = 0, failedFiles = 0, files; var fileGuids = [], fileNames = []; $(document).ready(function () { $("input[type='file']").change(function () { if (parseInt(this.files.length) > 10) { alert("Please select maximum of 10 files."); } else { $('span[id*="Validation"]').html(''); clearFileUploadFields(); files = this.files; fileCount = 0; for (i = 0; i < files.length; i++) { uploadFile(files[i], url, files[i].name); } showProgress(this); console.log($("#FileGuid").val()); } }); }); function showProgress(fileInput) { $("#submit").prop("disabled", true); currentLoaderRef = $(fileInput).parent().next().children("div.loader"); currentTickerRef = $(fileInput).parent().next().children("div.checkmark-cover"); currentLoaderRef.show(); //$("progress").show(); } function checkIfFileIsImage(fileType) { if (fileType.indexOf("image") == -1) { return true; } return false; } function uploadFile(file, url, originalFileName) { xhr = new XMLHttpRequest(); formData = new FormData(); xhr.open("POST", url, true); //Binding events to the request object xhr.upload.addEventListener("progress", uploadProgress, false); xhr.addEventListener("load", uploadComplete.bind(null, originalFileName), false); xhr.addEventListener("error", uploadFailed, false); xhr.addEventListener("abort", uploadCanceled, false); xhr.onreadystatechange = getResponseFromServer(xhr); formData.append("albumImage", file); xhr.send(formData); } //Progress event function uploadProgress(event) { if (event.lengthComputable) { //$(".percents").html(" " + ((event.loaded / event.total) * 100).toFixed() + "%"); $("progress").val(((event.loaded / event.total) * 100)); } else { alert("Failed to compute file upload length"); } } function getResponseFromServer(xhr) { if (xhr.readyState == 4 && xhr.status == 200) { } }; //Request complete event function uploadComplete(originalFileName, event) { var response = JSON.parse(event.originalTarget.response); fileCount++; switch (response.messageType) { case "success": uploadedFiles++; fileGuids.push(response.fileName); fileNames.push(originalFileName); updateUploadedFilesUl(originalFileName, '', true); $("#albumImageFileName").val($("#albumImageFileName").val() + originalFileName + ", "); if (fileCount == files.length) { $("#submit").prop("disabled", false); currentLoaderRef.hide(); currentTickerRef.addClass("opacity0"); //$("progress").hide(); $("#FileGuid").val(fileGuids.join('|')); $("#FileName").val(fileNames.join('|')); } break; case "largeFile": if (fileCount == files.length) { $("#submit").prop("disabled", false); currentLoaderRef.hide(); } updateUploadedFilesUl(originalFileName, response.message, false); break; case "wrongFileType": if (fileCount == files.length) { $("#submit").prop("disabled", false); currentLoaderRef.hide(); } updateUploadedFilesUl(originalFileName, response.message, false); break; case "exception": failedFiles++; if (fileCount == files.length) { $("#submit").prop("disabled", false); currentLoaderRef.hide(); //if (failedFiles == 0) // currentTickerRef.addClass("opacity0"); } updateUploadedFilesUl(originalFileName, response.message, false); break; } } function clearFileUploadFields() { $("#albumImageFileName").val(''); $("#uploadedFilesUL").html(''); $("#FileGuid").val(''); $("#FileName").val(''); fileCount = 0; uploadedFiles = 0; failedFiles = 0; fileGuids = []; fileNames = []; } function updateUploadedFilesUl(originalFileName, message, isFileUploaded) { if (isFileUploaded) { $("#uploadedFilesUL").append("<li class='success'>" + originalFileName + "</li>") } else { $("#uploadedFilesUL").append("<li class='failure'>" + originalFileName + " <b>upload failed, error: " + message + "</b></li>") } } //Request error event function uploadFailed(event) { hideAllLoadersAndCheckMarks(); $("#submit").prop("disabled", false); $("#message").html('A problem occured while uploading the image.'); //$("progress").hide(); } //Request cancel upload event function uploadCanceled(event) { } function hideAllLoadersAndCheckMarks() { $('.loader').hide(); $('.checkmark-cover').removeClass("opacity0"); }
错误原因
- 浏览器事件属性差异:Chrome不支持
event.originalTarget属性(该属性为Firefox特有),导致无法获取XHR对象的响应内容。 - 全局变量污染:
xhr和formData为全局变量,多文件上传时循环调用uploadFile会不断覆盖这两个变量,引发请求实例混乱。 - 事件绑定错误:
xhr.onreadystatechange = getResponseFromServer(xhr);直接执行函数并将空返回值赋值给事件,而非绑定函数引用。
修复方案
1. 全局变量改为局部变量
修改uploadFile函数,将xhr和formData声明为函数内局部变量,避免多文件上传时的变量覆盖:
function uploadFile(file, url, originalFileName) { const xhr = new XMLHttpRequest(); const formData = new FormData(); xhr.open("POST", url, true); xhr.upload.addEventListener("progress", uploadProgress, false); xhr.addEventListener("load", uploadComplete.bind(null, originalFileName), false); xhr.addEventListener("error", uploadFailed, false); xhr.addEventListener("abort", uploadCanceled, false); // 修正事件绑定方式 xhr.onreadystatechange = function() { getResponseFromServer(xhr); }; formData.append("albumImage", file); xhr.send(formData); }
2. 替换跨浏览器不兼容的事件属性
修改uploadComplete函数,用event.target替代event.originalTarget:
function uploadComplete(originalFileName, event) { var response = JSON.parse(event.target.response); fileCount++; // 后续原有逻辑保持不变 switch (response.messageType) { // ... 原有代码 } }
3. 可选优化:移除冗余事件处理
由于已经使用load事件处理请求完成逻辑,空的getResponseFromServer函数及对应的onreadystatechange绑定可直接移除,减少冗余代码。
验证
修改后重新测试,Chrome和Firefox均可正常处理多图片上传,不再抛出response未定义的错误。
内容的提问来源于stack exchange,提问作者Learning
相关产品推荐
相关产品推荐

