开发者问题收集

下载大尺寸json时Uncaught RangeError如何解决

2016-10-10
2114

我正在尝试下载大型 json 数据。 但它导致 Uncaught RangeError: 字符串长度无效

在此处输入图片描述

请帮忙解决这个问题,提前谢谢。

这是 Jsfiddle : http://jsfiddle.net/sLq3F/456/

3个回答

您可以使用 fetch()Response.body.getReader() (它们返回 ReadableStream )、 TextDecoder()Blob()URL.createObjectURL()

请注意,在具有有限 RAM 或可用磁盘空间较低的设备上,在 保存文件 对话框中单击 保存 之后,需要经过四分二十秒 4:20 才能关闭 保存文件 对话框,然后再过一分三十秒 1:30 才能从文件管理器 GUI 上的文件中删除 .crdownload 扩展名。在第一个 4:20 期间,文件正在下载到文件系统并且 保存文件 对话框可见,鼠标指针是可移动的,尽管 UI 暂时对点击或尝试更改选项卡没有响应。当 保存文件 对话框关闭且文件仍在下载到文件系统时,扩展名为 .crdownload ,UI 将返回正常功能。

在上述过程结束时,文件已成功下载到本地文件系统,总大小为 189.8 MB (189,778,220 字节)

<!DOCTYPE html>
<html>

<head>
  <style>
    code {
      color:navy;
      background-color:#eee;
      padding:2px;
    }
  </style>
</head>

<body>
  <button>Request File</button><br>
  <progress min="0" max="189778220" value="0"></progress>
  <output></output>
  <br><br>
  <label></label>
  <script>
    var url = "https://raw.githubusercontent.com/zemirco/sf-city-lots-json/master/citylots.json";
    var button = document.querySelector("button");
    var progress = document.querySelector("progress");
    var label = document.querySelector("label");
    var output = document.querySelector("output");
    
    var request = (url) => {
      
      label.innerHTML = `Requesting <code>${url}</code> at ${new Date()}.<br><br>`;
      
      return fetch(url)
      .then(response => response.body.getReader())
      .then(reader => {
        var decoder = new TextDecoder();
        var json = "";
        label.innerHTML += `Request successful.<br><br>Reading request body at ${new Date()}.<br><br>`;
        return reader.read().then(function processData(result) {
            if (result.done) {
              // do stuff when `reader` is `closed`
              return reader.closed.then(function() {
                // return `json` string
                return json;
              });
            };
            json += decoder.decode(result.value);
            output.innerHTML = ` ${json.length} of ${progress.max} bytes read`;
            progress.value = json.length;
            return reader.read().then(processData)
          })
          .then(function(data) {
            var message = `Reading of <code>${url}</code> complete at ${new Date()}. <br><br>` 
                               + `${data.length} total bytes read. `
                               + `Please allow up to 4 minutes for file to download `
                               + `to filesystem after clicking <code>Save</code>.<br><br>`;
            label.innerHTML += message;
            
            var blob = new Blob([data], {
              type: "application/json"
            });
            var file = URL.createObjectURL(blob);
            var a = document.createElement("a");
            a.download = "citylots.json";
            a.href = file;
            document.body.appendChild(a);
            a.click();
            var closeBlob = (e) => {
              window.removeEventListener("focus", closeBlob);
              blob.close();
              URL.revokeObjectURL(file);
            };
            window.addEventListener("focus", closeBlob);
            return message.replace(/<[^>]*>/g, "");
          })
          .catch(function(err) {
            console.log("err", err)
          })
      });
    }
    
    var handleRequest = (e) => {
      button.setAttribute("disabled", "disabled");
      request(url).then(function(message) {
        console.log(message);
        button.removeAttribute("disabled");
      })
    };
    
    button.addEventListener("click", handleRequest);
  </script>
</body>
</html>

plnkr https://plnkr.co/edit/gewixzHZSKRXquZ2OVF2?p=preview

guest271314
2016-10-13

我猜你需要循环遍历 JSON 文件中的某些内容并将其拆分为更易于管理的字符串。

汤姆

你有 JSON 文件的示例片段吗?

Thomas Ward
2016-10-10

您的服务器是否运行 PHP?

如果有,我认为您绝对必须检查 PHP.ini 文件或运行 phpinfo 页面,因为即使不是外部请求,php 设置也会限制文件传输的大小。其他语言也可以这样做,但除了 PHP 之外,我从未遇到过此问题。

附言:我没有看到文件的大小

JeanMGirard
2016-10-13