【问题标题】:html5 multiple xmlhttprequest more responsehtml5 多个 xmlhttprequest 更多响应
【发布时间】:2012-08-04 06:59:50
【问题描述】:

大家好!

我的 HTML5 XMLHttprequest 上传器有点问题。

我从 多个文件输入 中读取具有 Filereader 类的文件,然后以二进制字符串的形式上传一个。在服务器上,我捕获输入流中的位,将其放入 tmp 文件等。这部分很好。程序正常终止,发送响应,我在标题中看到它(例如使用 FireBug)。 但是对于 JS,我只捕获了 'onreadystatechange' 中的最后一个。

我没有看到所有回复。为什么?如果有人能解决这个问题,那就太好了:)

你会看到相同的 jQuery 和模板,别担心 :D

这是 JS:

function handleFileSelect(evt)
{
    var files = evt.target.files; // FileList object

    var todo = {
            progress:function(p){
                $("div#up_curr_state").width(p+"%");
                },

            success:function(r,i){

                $("#img"+i).attr("src",r);
                $("div#upload_state").remove();
                },

            error:function(e){
                alert("error:\n"+e);
                }
        };


    // Loop through the FileList and render image files as thumbnails.
    for (var i = 0, f; f = files[i]; i++) {
        // Only process image files.
        if (!f.type.match('image.*')) {
            continue;
        }

        var reader = new FileReader();
        var row = $('ul#image_list li').length;
            row = row+i;
        // Closure to capture the file information.
        reader.onload = (function(theFile,s) {
            return function(e) {
            // Render thumbnail.
            $("span#prod_img_nopic").hide();
            $("div#prod_imgs").show();
            var li = document.createElement('li');
            li.className = "order_"+s+" active";
            li.innerHTML = ['<img class="thumb" id="img'+s+'" src="', e.target.result,
                                '" title="', escape(theFile.name), '"/><div id="upload_state"><div id="up_curr_state"></div>Status</div>'].join('');
            document.getElementById('image_list').insertBefore(li, null);
            };
        })(f,row);

        // Read in the image file as a data URL.
        reader.readAsDataURL(f);

        //upload the data
        //@param object fileInputId     input file id
        //@param int    fileIndex       index of fileInputId
        //@param string URL             url for xhr event
        //@param object todo            functions of progress, success xhr, error xhr
        //@param string method          method of xhr event-def: 'POST'

        var url = '{/literal}{$Conf.req_admin}{$SERVER_NAME}/{$ROOT_FILE}?mode={$_GET.mode}&action={$_GET.action}&addnew=product&imageupload={literal}'+f.type;

        upload(f, row, url, todo);
}

上传功能:

function upload(file, fileIndex, Url, todo, method)
 {
        if (!method) {
            var method = 'POST';
        }

        // take the file from the input

        var reader = new FileReader();
        reader.readAsBinaryString(file); // alternatively you can use readAsDataURL
        reader.onloadend  = function(evt)
        {
                // create XHR instance
                xhr = new XMLHttpRequest();

                // send the file through POST
                xhr.open(method, Url, true);

                // make sure we have the sendAsBinary method on all browsers
                XMLHttpRequest.prototype.mySendAsBinary = function(text){
                    var data = new ArrayBuffer(text.length);
                    var ui8a = new Uint8Array(data, 0);
                    for (var i = 0; i < text.length; i++) ui8a[i] = (text.charCodeAt(i) & 0xff);
                    var bb = new (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder)(); 
                    bb.append(data);
                    var blob = bb.getBlob();
                    this.send(blob);
                }

                // let's track upload progress
                var eventSource = xhr.upload || xhr;
                eventSource.addEventListener("progress", function(e) {
                    // get percentage of how much of the current file has been sent
                    var position = e.position || e.loaded;
                    var total = e.totalSize || e.total;
                    var percentage = Math.round((position/total)*100);
                    // here you should write your own code how you wish to proces this
                    todo.progress(percentage);        
                });

                // state change observer - we need to know when and if the file was successfully uploaded
                xhr.onreadystatechange = function()
                {  
                        if(xhr.status == 200 && xhr.readyState == 4)
                        {                                
                            // process success                               
                            resp=xhr.responseText;

                            todo.success(resp,fileIndex);
                        }else{
                            // process error
                            todo.error(resp);
                        }                            
                };

                // start sending
                xhr.mySendAsBinary(evt.target.result);
        };
   }

    }
}

和启动事件

document.getElementById('files').addEventListener('change', handleFileSelect, false);

【问题讨论】:

  • “仅捕获 onreadystatechange 中的最后一个响应”是什么意思?你期待什么?
  • 它只是看起来还是每次更改一个文件时都上传所有文件?而且,您不应该 [需要] 重复设置 `XMLHttpRequest.prototype.mySendAsBinary` 方法 - 它是一个原型。
  • todo.success(..) 函数将响应设置为 img src。如果我上传 3 个文件,然后我等待三个响应(更改 src)。但只有最后的反应和形象改变。如果我看到一些程序的帖子回复,其他回复也会出现。你懂我吗?

标签: javascript html xmlhttprequest response


【解决方案1】:

这是一个很小的错误:您忘记添加 var 声明:

    // create XHR instance
    var xhr = new XMLHttpRequest();
//  ^^^ add this

使用像你这样的 readystatechange 处理函数

function() {  
    if (xhr.status == 200 && xhr.readyState == 4) {       
        resp=xhr.responseText; // also a missing variable declaration, btw
        todo.success(resp,fileIndex);
    } else {
        todo.error(resp);
    }                            
}

当任何请求触发事件时,仅检查了最新的 xhr 实例的 statusreadyState。因此,只有当最后一个 xhr 触发事件本身时,才会执行成功函数。

解决方案:修复所有变量声明,我想这不是唯一一个(尽管严重影响行为)。您还可以使用 this 而不是 xhr 作为对事件处理程序中当前 XMLHttpRequest 实例的引用。

【讨论】:

  • 哇。谢谢你的帮助。很好。我没有看到这个错误。
  • 有时最大的错误也是最小的错误。当我 10 岁的时候,我从杂志上输入 BASIC 代码,是单个字符的错误让我着迷。几十年过去了,这仍然是小事。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-19
  • 1970-01-01
  • 2021-09-03
  • 2011-08-07
  • 1970-01-01
相关资源
最近更新 更多