无法将ArrayBuffer转换为Base64,Ajax POST请求失败并触发500内部服务器错误——谷歌云盘文件转存至服务端问题
解决Google Drive文件获取、Base64转换及Ajax POST 500错误问题
我来帮你一步步排查并解决这些问题:
1. 优先修复ArrayBuffer转Base64的核心问题
你的500错误很大概率是因为Base64转换失败,导致后端Convert.FromBase64String抛出异常。先替换一个可靠的base64ArrayBuffer实现,这个是标准的ArrayBuffer转Base64方法:
function base64ArrayBuffer(arrayBuffer) { var base64 = ''; var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; var bytes = new Uint8Array(arrayBuffer); var byteLength = bytes.byteLength; var byteRemainder = byteLength % 3; var mainLength = byteLength - byteRemainder; var a, b, c, d; var chunk; // 处理3字节一组的块 for (var i = 0; i < mainLength; i = i + 3) { chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]; a = (chunk & 16515072) >> 18; b = (chunk & 258048) >> 12; c = (chunk & 4032) >> 6; d = chunk & 63; base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]; } // 处理剩余的1-2字节及补位 if (byteRemainder == 1) { chunk = bytes[mainLength]; a = (chunk & 252) >> 2; b = (chunk & 3) << 4; base64 += encodings[a] + encodings[b] + '=='; } else if (byteRemainder == 2) { chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1]; a = (chunk & 64512) >> 10; b = (chunk & 1008) >> 4; c = (chunk & 15) << 2; base64 += encodings[a] + encodings[b] + encodings[c] + '='; } return base64; }
2. 完善Ajax请求的错误处理与调试
当前代码只处理了xhr成功的情况,没有捕获请求失败场景,导致你看不到Ajax未触发的原因。给xhr加上错误监听,同时优化Ajax的错误回调:
// 修改xhr部分代码 var xhr = new XMLHttpRequest(); xhr.open("GET", "https://www.googleapis.com/drive/v3/files/" + fileId + '?alt=media', true); xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken); xhr.responseType = 'arraybuffer'; // 新增xhr网络错误监听 xhr.onerror = function() { console.error('获取Google Drive文件失败:', xhr.statusText); alert('获取文件时发生网络错误,请检查权限或网络连接'); }; xhr.onreadystatechange = function () { if (xhr.readyState == 4) { if (xhr.status == 200) { base64 = base64ArrayBuffer(xhr.response); $.ajax({ type: "POST", url: "googledrive.aspx/GetDriveFile", data: JSON.stringify({ FileName: inputFileName, Base64: base64 }), contentType: "application/json; charset=utf-8", dataType: "json", success: function (msg) { if (msg.d == "true") { alert("Success"); } else { alert("Failed: " + msg.d); } }, error: function (xhr, status, error) { // 打印详细错误到控制台方便调试 console.error('Ajax请求错误:', status, error); console.error('响应内容:', xhr.responseText); alert('上传失败,请查看控制台获取详细错误信息'); } }); } else { console.error('获取文件失败,状态码:', xhr.status, xhr.statusText); alert('获取文件失败,状态码: ' + xhr.status); } } } xhr.send();
3. 修复后端代码的潜在问题
后端500错误还可能来自两个点:UploadedFiles文件夹不存在,或者Base64字符串包含无效字符。修改后端代码如下:
public static string GetDriveFile(string FileName, string Base64) { try { string uploadDir = HttpContext.Current.Server.MapPath("UploadedFiles/"); // 检查并创建上传文件夹 if (!Directory.Exists(uploadDir)) { Directory.CreateDirectory(uploadDir); } string inputPath = Path.Combine(uploadDir, FileName); // 清理Base64中的无效字符(换行、空格等) Base64 = Base64.Replace("\r", "").Replace("\n", "").Replace(" ", ""); byte[] image64 = Convert.FromBase64String(Base64); File.WriteAllBytes(inputPath, image64); return "true"; } catch (Exception ex) { // 返回详细异常信息方便前端调试 return ex.ToString(); } }
额外优化建议
- 前端中
inputFileName有重复赋值的冗余逻辑,直接使用randomString(8) + "." + fileext的结果即可,无需再从DOM取值。 - 确保
maxFileSize是正确的字节数(比如10MB对应10*1024*1024),避免大小判断出错。 - 可以在前端提前验证Base64字符串有效性,比如尝试解码,提前发现转换问题。
内容的提问来源于stack exchange,提问作者coder
相关产品推荐
相关产品推荐

