【问题标题】:Sending large javascript array to Web API将大型 javascript 数组发送到 Web API
【发布时间】:2015-04-05 18:13:18
【问题描述】:

我在这个问题上苦苦挣扎了 2 天...

我有一个 JavaScript 数组(20,000K 行和 41 列)。它最初是通过 ajax 调用在 javaScript 中接收的,如下所示,

var dataArray = [];
var dataRequest = {};
            dataRequest.SearchCondition = 'some value'; 
            $.ajax({
                type: "POST",
                url: "api/GetData/ProcessRequest",              
                dataType: 'json',
                cache: false,
                async: true,
                crossDomain: false,
                data: dataRequest ,
                success: function (response) {
                  dataArray = response; 
                },
                error: function (xhr, textStatus, errorThrown) {
                   dataArray = null;
                }
            });

在应用程序中,用户将验证数据并将其发送回 Web API 方法。

我正在尝试将相同的数据 (dataArray) 发送回 web api 方法,但是它失败了。请看下面的代码,

选项 1:(失败 - 请求未命中 web api 方法)

 var dataArrayJsonStr = JSON.stringify(dataArray);                     

    $.ajax({
        type: "POST",
        url: "api/SendData/ProcessRequest",
        dataType: 'json',
        data: {'dataValue':dataArrayJsonStr },
        success: function (response) {
            alert('success');
        },
        error: function (xhr, textStatus, errorThrown) {
            alert(errorThrown)
        }
    });

在 IE 8 中,出现“内存不足”异常弹出窗口。 (我们的大多数应用程序用户仍然使用 IE 8)

在 Chrome 中,它会崩溃。

选项2试过了:(不知道怎么读值)

我尝试通过 XmllHttpRequest 向 web api 发送相同的值

var dataArrayJsonStr = JSON.stringify(dataArr);
            var xmlRequest;
            if (window.XMLHttpRequest) {
                xmlRequest = new XMLHttpRequest();                
            }
            xmlRequest.open("POST", "api/SendData/ProcessRequest", false);
            xmlRequest.setRequestHeader('Content-Type', 'application/text');
            xmlRequest.send("dataValue=" + dataArrayJsonStr);

使用 Chrome,我能够成功地将数据发布到 Web API,我看到内容长度为“128180309”。但是,我看不到这些值。如何获取 Web API 中的值?

请建议我如何将大数据从 javascript 发送回 web api。

谢谢, 虚拟机

【问题讨论】:

    标签: javascript jquery ajax asp.net-web-api xmlhttprequest


    【解决方案1】:

    尝试为API增加更多内存或更多时间执行,也可以尝试更多小部分返回数据。定义要发送的部件数量。

    【讨论】:

    • 能否提供代码示例或参考文章以小部分返回数据?
    • 我会搜索一篇文章,但更多的是逻辑,你从数组中获取长度,然后 var numbers_object = object / 1000(registres);并执行响应每个或我搜索一个例子或创建一个想法
    • 在这种情况下,我如何在 Web API 中接收数据并使其成为单个对象?
    • 我认为是这样的: global array= [][] function get_data(){ part = request.part; part_data = request.data;结束 = part_data.length * 部分;计数=结束-part_data.length; for(count;count
    • 如果用户只检查信息但不更新任何内容,请在您的 api 中保存相同的数据,然后再将其发送到全局变量中,并根据用户的响应,使用此数据保存。仅当用户不更新数据时才这样做。
    【解决方案2】:

    您是否尝试按块发送数据? 我的意思是,您需要将其拆分成小块并执行多个请求。

    例如,它可以是:

    --HELLO SERVER. STARTING TRANSMITION FOR DATA SET #177151--  
    PIECE 1/13  
    PIECE 2/13  
    ...  
    PIECE 13/13  
    --BUE SERVER-- 
    

    因此,这需要一些时间,但您可以发送任意数量的数据而不会出现内存问题。如果您为此苦苦挣扎了 2 天,我认为您有时间编写代码 :)

    UPD1:客户端代码示例。

    这是客户端代码的示例。这是一个简单的分块算法。 不得不说我没有测试它,因为它需要很长时间才能代表你的情况。

    所以,你应该阅读它并明白这一点。 你有一个简单的函数,它为每个响应获取整个数据集和回调(例如更新你的进度条),成功完成和错误。

    希望它能帮助你解决一些问题。 另外,我可以帮助您在服务器端构建架构,但我需要知道您使用什么技术。

    function sendData(data, onEach, onFinish, onError) {
        var CHUNK_SIZE = 1000;
        var isFailed = false;
        var chunkNum = 0;
        var chunk, chunkStart, chunkEnd;
    
        while(data.length + CHUNK_SIZE > chunkNum * CHUNK_SIZE) {
            if(isFailed) {
                return;
            }
            chunkStart = chunkNum * CHUNK_SIZE;
            chunkEnd   = chunkStart + CHUNK_SIZE + 1;
    
            chunk = {
                num: chunkNum,
                data: data.slice(chunkStart, chunkEnd)
            };
    
            ajaxCall(chunk);
            chunkNum++;
        }
    
        function ajaxCall(data) {
            $.ajax({
                type: "POST",
                url: "api/GetData/ProcessRequest",              
                dataType: 'json',
                async: true,
                data: dataRequest ,
                success: function (response) {
                    onEach(data, response);
                },
                error: function (xhr, textStatus, errorThrown) {
                    isFailed = true;
                    onError(arguments);
                }
            });
        }
    
    
    }
    

    【讨论】:

    • 另外,您可以将当前块的数量与整个请求一起发送,并异步发送所有请求。然后服务器将能够在收到最后一块时以正确的顺序构造正确的数据集
    • 感谢您的建议。我没有尝试按块发送数据。你能提供我的代码示例吗?
    • 您也可以修改代码以发送“hello message”并告诉服务器,他应该接收多少个块,并为每个单独的传输提供一个在服务器端生成的 uniq id 作为响应关于“你好消息”
    • 感谢代码示例。我今天会试试。早些时候,我尝试在 HTML5 中使用 Blob,它在 Chrome 中完美运行,但在 IE8 中不支持,因为它不受支持。不过有个问题……在 ProcessRequest 方法中,我们如何将块组合成一个完整的对象?
    • 为什么不能只发送用户使用“客户端版本”数据和服务器版本创建的数据之间的差异?我的意思是,用户需要 20k 行,而他只更改了其中的几行。为什么不能只发回更改的行并让服务器知道其他行没有更改?就像版本控制系统只发送文件的difference 而不是整个文件
    【解决方案3】:

    我认为你创造了开销,也许我错了,你可以编辑我。 您真的需要发回所有数据还是只需要发送修改后的数据? 因为在现实生活中很难想象用户会查看 20.000 行。

    ExtJS 商店就是很好的例子,你可以看例子here 商店的关键是他们发回服务器的只是修改或删除的数据,它节省了浏览器、网络和服务器资源。

    【讨论】:

    • 我要把所有的数据都发回去。
    猜你喜欢
    • 1970-01-01
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-29
    相关资源
    最近更新 更多