Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
289 views
in Technique[技术] by (71.8m points)

javascript - How to solve Uncaught RangeError when download large size json

I am trying to download the large json data. But it leads to Uncaught RangeError: Invalid string length.

enter image description here

Pls help to solve this problem,Thanks in advance.

Here is the Jsfiddle : http://jsfiddle.net/sLq3F/456/

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use fetch(), Response.body.getReader() which returns a ReadableStream, TextDecoder(), Blob(), URL.createObjectURL().

Note, at device having limited RAM or low available disk space, after clicking Save at Save File dialog four minutes and twenty seconds 4:20 elapsed before the Save File dialog closed, followed by an additional one minute and thirty seconds 1:30 before the .crdownload extension was removed from the file at file manager GUI. During the first 4:20 period where the file is downloading to filesystem and the Save File dialog is visible the mouse pointer is movable, though the UI is temporarily unresponsive to clicks or attempts to change tabs. When the Save File dialog closes and the the file is still downloading to filesystem, having extension .crdownload the UI returns to normal functionality.

At the conclusion of the process described above the file was successfully downloaded to local filesystem having a total size of 189.8 MB (189,778,220 bytes).

<!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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...