如何用$.ajax在JavaScript中保存Zip二进制数据并解决损坏问题
解决Ajax下载Zip文件损坏的问题
问题核心:jQuery 3.6.0的$.ajax对responseType: "arraybuffer"的支持存在缺陷,会自动将二进制响应转成UTF-8字符串,破坏Zip文件的二进制结构,导致打开时报错。Postman能正常工作是因为它正确保留了原始二进制响应。
方案1:改用原生XMLHttpRequest(推荐)
直接通过原生XHR处理二进制响应,避开jQuery的自动转换逻辑:
$("#get-token-button").click(function() { $.ajax({ url: "https://localhost:9445/test-org/api-test/oauth-test-provider/oauth2/token", type: "POST", data: { grant_type: "client_credentials", client_id: "client_id", client_secret: "client_secret", scope: "scope" }, success: function(response) { alert("Token: " + response.access_token); // 用原生XHR发起下载请求 const xhr = new XMLHttpRequest(); xhr.open("POST", "https://localhost:9445/test-org/api-test/API/v1/ReceiptService/getReceiptByDataDate"); xhr.setRequestHeader("Authorization", "Bearer " + response.access_token); xhr.setRequestHeader("Content-Type", "application/json"); xhr.responseType = "arraybuffer"; // 明确指定响应为二进制数组 xhr.onload = function() { if (xhr.status === 200) { const blob = new Blob([xhr.response], {type: "application/zip"}); const url = window.URL.createObjectURL(blob); $("#download-link").attr("href", url); $("#download-link").attr("download", "file.zip"); $("#download-link").show(); } else { alert("Download failed: " + xhr.statusText); } }; xhr.onerror = function() { alert("Download failed: Network error"); }; // 发送请求体数据 xhr.send(JSON.stringify({ "dataDate": "Date", "ogaTaxNum": "TaxNum" })); }, error: function(jqXHR, textStatus, errorThrown) { alert("Token request failed: " + errorThrown); } }); });
方案2:修复jQuery Ajax调用
如果必须保留jQuery,需要手动设置XHR的响应类型,并从jqXHR对象直接获取原始二进制数据:
$("#get-token-button").click(function() { $.ajax({ url: "https://localhost:9445/test-org/api-test/oauth-test-provider/oauth2/token", type: "POST", data: { grant_type: "client_credentials", client_id: "client_id", client_secret: "client_secret", scope: "scope" }, success: function(response) { alert("Token: " + response.access_token); $.ajax({ url: "https://localhost:9445/test-org/api-test/API/v1/ReceiptService/getReceiptByDataDate", type: "POST", headers: { "Authorization": "Bearer " + response.access_token }, data: JSON.stringify({ "dataDate": "Date", "ogaTaxNum": "TaxNum" }), contentType: "application/json", processData: false, // 禁用jQuery对请求数据的自动处理 beforeSend: function(xhr) { xhr.responseType = "arraybuffer"; // 手动设置响应类型 }, complete: function(jqXHR) { if (jqXHR.status === 200) { const blob = new Blob([jqXHR.response], {type: "application/zip"}); const url = window.URL.createObjectURL(blob); $("#download-link").attr("href", url); $("#download-link").attr("download", "file.zip"); $("#download-link").show(); } else { alert("Download failed: " + jqXHR.statusText); } }, error: function(jqXHR, textStatus, errorThrown) { alert("Download failed: " + errorThrown); } }); }, error: function(jqXHR, textStatus, errorThrown) { alert("Token request failed: " + errorThrown); } }); });
验证注意事项
- 确认API返回的
Content-Type响应头为application/zip或application/octet-stream - 下载后可通过哈希校验工具,对比Postman下载的文件与当前代码下载的文件,验证数据一致性
内容的提问来源于stack exchange,提问作者Mariel
相关产品推荐
相关产品推荐

