如何使用JavaScript中的$.ajax保存zip二进制数据。

huangapple go评论56阅读模式
英文:

how to save binary data of zip with $.ajax in javascript

问题

您遇到的问题可能是由于下载的ZIP文件格式不正确或已损坏而导致的。要解决这个问题,您可以尝试以下几个步骤:

  1. 检查服务器端的ZIP文件生成代码: 首先,请确保服务器端生成的ZIP文件没有问题。您可以在服务器端检查ZIP文件的生成过程,确保它们以正确的ZIP格式生成。

  2. 修改前端代码: 在前端代码中,您可以尝试更改以下部分:

    responseType: "blob", // 将 responseType 设置为 "blob"
    

    这将确保从服务器接收到的响应以二进制Blob的形式处理,而不是字符串。这可能会有助于解决ZIP文件格式问题。

  3. 检查服务器响应头: 确保服务器在响应ZIP文件时正确设置了响应头,特别是Content-Type。应该将Content-Type设置为application/zipapplication/octet-stream,以确保浏览器正确解析ZIP文件。

  4. 调试错误消息: 如果下载仍然失败,您可以在前端代码中的错误处理部分查看错误消息,以获取有关问题的更多信息。将响应中的错误消息打印到控制台可能会有所帮助。

请尝试上述步骤,看看是否能够解决您的问题。如果问题仍然存在,请提供更多关于服务器端生成ZIP文件的信息,以便进一步帮助您解决问题。

英文:

I have problem when I run script it can download zip file but when open zip file it show error
"The archive is either in unknow format or damaged"

Before write this script I try Webservice in Postman and use save responce "save to a file " i can get zip file and can use it

This is my code

javascript:

<a id="download-link" style="display: none;">Download</a>

<button id="get-token-button">Get OAuth 2.0 Token</button>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

<script>

    $("#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",
        responseType: "arraybuffer",
        success: function(response) {
          alert(response);
          // If the request is successful, create a blob from the response and create a download link
          var blob = new Blob([response], {type: "application/zip"});
          var url = window.URL.createObjectURL(blob);
          $("#download-link").attr("href", url);
          $("#download-link").attr("download", "file.zip");
          $("#download-link").show();
        },
        error: function(jqXHR, textStatus, errorThrown) {
          // If the request fails, display an error message
          alert("Download failed: " + errorThrown);
        }
      });
    },
    error: function(jqXHR, textStatus, errorThrown) {
      // If the request fails, display an error message
      alert("Token request failed: " + errorThrown);
        }
      });
    });
  </script>

I want solution how to download zip file

答案1

得分: 0

response 是一个字符串。默认情况下,它尝试将响应解释为 UTF8,这可能会损坏一些数据(因为源数据是二进制的)。为了防止以这种方式损坏数据,您可以在 ajax 设置中添加 mimeType: 'text/plain; charset=x-user-defined'

此外,在创建 blob 时,字符串中的字符应映射到从 0 到 255 的值,可以通过 Uint8Array.from(response, a => a.charCodeAt(0)) 来实现。因此,您可以像这样创建 blob:

var blob = new Blob([Uint8Array.from(response, a => a.charCodeAt(0))], {type: "application/zip"});

编辑
当我搜索避免旧的 x-user-defined 技巧的方法时,我发现了另一个主题。因此,在使用 jQuery 3 时,可以通过以下方式完全避免它:

xhrFields: {responseType: 'blob'}

在设置中,响应可以像这样使用:

var url = window.URL.createObjectURL(response);

在这里,您甚至不必手动创建 blob,因为响应已经是一个 blob。

该主题的另一个答案 显示了如何仅为成功的响应更改 xhr: 设置,以将其设置为仅 blob。

英文:

The response is a string in this case. By default, it tries to interpret the response as UTF8, which is likely to corrupt some data (as the source data is binary). To prevent corrupting the data this way, you can add mimeType: 'text/plain; charset=x-user-defined' to the ajax settings.

Also, when creating a blob, the characters in the string should be mapped to values from 0 to 255, which can be done by Uint8Array.from(response, a => a.charCodeAt(0)).
So, you can create the blob like this:

var blob = new Blob([Uint8Array.from(response, a => a.charCodeAt(0))], {type: "application/zip"});

EDIT:
As I was searching for ways to avoid the old x-user-defined trick I came across another thread. So, with jQuery 3 it is possible to avoid it entirely using:

xhrFields: {responseType: 'blob'}

in the settings and the response can be used the following way:

var url = window.URL.createObjectURL(response);

Here, you don't even have to manually create the blob anymore as the response is already a blob.

Another answer to that thread shows you how to set it to blob only for successful response, by changing the xhr: setting.

huangapple
  • 本文由 发表于 2023年5月10日 17:08:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76216683.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定