Firefox 7/8 中出现 XHR.send 错误,但 FF6/Chrome 中没有:0x80460001 (NS_ERROR_CANNOT_CONVERT_DATA)

发布于 2024-12-12 07:47:44 字数 4574 浏览 7 评论 0原文

我在 Firefox 7/8 中的拖放文件上传脚本时遇到问题。我编写了一个基本脚本,用于将放入 html 文档 dropzone 的文件上传到服务器端脚本“save.php”。包含 JavaScript 的完整 html 可以在下面找到。服务器端部分不是问题,因此我将其省略(save.php)。

我搜索并尝试了一切,但现在我真的陷入困境。当我删除要上传的文件时,该脚本在 firefox 6 和 chrome 中运行,没有任何 javascript 错误(此外,该文件正确保存在调用 save.php 的服务器上)。 但在 ff7/8 中,当我将文件放到 dropzone 上进行上传时,我在 Firebug 控制台中收到以下错误:

组件返回的失败代码:0x80460001 (NS_ERROR_CANNOT_CONVERT_DATA) this.send(ui8a.buffer); newfu.html(第105行)

有人能告诉我我做错了什么吗?这是 Firefox 7/8 的错误吗?那么为什么它可以在 chrome 和 firefox 6 中工作呢?

我在 xhr.send() 中发送的字符串是否未正确编码?

非常感谢您的帮助!

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>cross browser drag and drop file upload example</title>
<script language="javascript" type="text/javascript" src="../js/jquery/js/jquery-1.6.4.min.js"></script>
<script>
    // add the dataTransfer property for use with the native `drop` event
    // to capture information about files dropped into the browser window
    jQuery.event.props.push("dataTransfer");

    $(function() {
        $('#dropzone').bind("drop",function(evnt) {
            evnt.stopPropagation();
            evnt.preventDefault();

            var data = evnt.dataTransfer;
            for (var i = 0; i < data.files.length; i++) {
                var file = data.files[i];


                var boundary = '------multipartformboundary' + (new Date).getTime();
                var dashdash = '--';
                var crlf     = '\r\n';

                // Build RFC2388 string
                var builder = '';
                var builder2 = '';

                builder += dashdash;
                builder += boundary;
                builder += crlf;

                // generate headers            
                builder += 'Content-Disposition: form-data; name="user_file[]"';
                if (file.fileName) {
                  builder += '; filename="' + file.fileName + '"';
                }
                builder += crlf;

                builder += 'Content-Type: application/octet-stream';
                builder += crlf;
                builder += crlf; 

                //
                // binary data string in FileReader's onload (see below)
                //

                builder2 += crlf;

                //write boundary
                builder2 += dashdash;
                builder2 += boundary;
                builder2 += crlf;

                // mark end of the request
                builder2 += dashdash;
                builder2 += boundary;
                builder2 += dashdash;
                builder2 += crlf;


                // setup filereader: read file and send it
                reader = new FileReader();
                reader.onload = function(evt) {
                    binary = evt.target.result;

                    var xhr = new XMLHttpRequest();
                    xhr.open("POST", "save.php", true);
                    xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=' + boundary);

                    //sendAsBinary: deprecated Mozilla only, define NEWsendAsBinary and use it in all browsers
                    if(!XMLHttpRequest.prototype.NEWsendAsBinary){
                        XMLHttpRequest.prototype.NEWsendAsBinary = function(datastr) {
                            function byteValue(x) {
                              return x.charCodeAt(0) & 0xff;
                            }
                            var ords = Array.prototype.map.call(datastr, byteValue);
                            var ui8a = new Uint8Array(ords);
                            this.send(ui8a.buffer);
                        }
                    }   
                    xhr.NEWsendAsBinary(builder+binary+builder2);
                };
                //read binary data
                reader.readAsBinaryString(file);
            }
            return false;
        }).bind ("dragover",function(evt) {
                evt.stopPropagation();
                evt.preventDefault();
                $(this).css({
                              border: '1px solid #ff0000'
                           });
                return false;
        });
    });
</script>
</head>
<body>
    <div id="dropzone">
        <p>Drop Files Here</p>
    </div>
</body>
</html>

i'm having problems with a drag and drop file upload script in firefox 7/8. i have written a basic script to upload files dropped into the dropzone of the html document to a server-side script "save.php". the full html including the javascript can be found below. the server-side part is not a problem and therefore i left it out (save.php).

i searched and tried everything but now i'm really stuck. the script runs in firefox 6 and also in chrome without any javascript error when i drop a file to upload (furthermore, the file is correctly saved on the server calling save.php).
but in ff7/8 i get the following error in the firebug console when i drop a file on the dropzone to upload:

Component returned failure code: 0x80460001 (NS_ERROR_CANNOT_CONVERT_DATA)
this.send(ui8a.buffer); newfu.html (Line 105)

can anybody tell me what i am doing wrong? is this a bug of firefox 7/8? then why does it work in chrome AND firefox 6?

is the string i send in xhr.send() not correctly encoded?

thanks a lot for any help!

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>cross browser drag and drop file upload example</title>
<script language="javascript" type="text/javascript" src="../js/jquery/js/jquery-1.6.4.min.js"></script>
<script>
    // add the dataTransfer property for use with the native `drop` event
    // to capture information about files dropped into the browser window
    jQuery.event.props.push("dataTransfer");

    $(function() {
        $('#dropzone').bind("drop",function(evnt) {
            evnt.stopPropagation();
            evnt.preventDefault();

            var data = evnt.dataTransfer;
            for (var i = 0; i < data.files.length; i++) {
                var file = data.files[i];


                var boundary = '------multipartformboundary' + (new Date).getTime();
                var dashdash = '--';
                var crlf     = '\r\n';

                // Build RFC2388 string
                var builder = '';
                var builder2 = '';

                builder += dashdash;
                builder += boundary;
                builder += crlf;

                // generate headers            
                builder += 'Content-Disposition: form-data; name="user_file[]"';
                if (file.fileName) {
                  builder += '; filename="' + file.fileName + '"';
                }
                builder += crlf;

                builder += 'Content-Type: application/octet-stream';
                builder += crlf;
                builder += crlf; 

                //
                // binary data string in FileReader's onload (see below)
                //

                builder2 += crlf;

                //write boundary
                builder2 += dashdash;
                builder2 += boundary;
                builder2 += crlf;

                // mark end of the request
                builder2 += dashdash;
                builder2 += boundary;
                builder2 += dashdash;
                builder2 += crlf;


                // setup filereader: read file and send it
                reader = new FileReader();
                reader.onload = function(evt) {
                    binary = evt.target.result;

                    var xhr = new XMLHttpRequest();
                    xhr.open("POST", "save.php", true);
                    xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=' + boundary);

                    //sendAsBinary: deprecated Mozilla only, define NEWsendAsBinary and use it in all browsers
                    if(!XMLHttpRequest.prototype.NEWsendAsBinary){
                        XMLHttpRequest.prototype.NEWsendAsBinary = function(datastr) {
                            function byteValue(x) {
                              return x.charCodeAt(0) & 0xff;
                            }
                            var ords = Array.prototype.map.call(datastr, byteValue);
                            var ui8a = new Uint8Array(ords);
                            this.send(ui8a.buffer);
                        }
                    }   
                    xhr.NEWsendAsBinary(builder+binary+builder2);
                };
                //read binary data
                reader.readAsBinaryString(file);
            }
            return false;
        }).bind ("dragover",function(evt) {
                evt.stopPropagation();
                evt.preventDefault();
                $(this).css({
                              border: '1px solid #ff0000'
                           });
                return false;
        });
    });
</script>
</head>
<body>
    <div id="dropzone">
        <p>Drop Files Here</p>
    </div>
</body>
</html>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

婴鹅 2024-12-19 07:47:44

我不知道为什么会出现这个错误,但是既然Fx支持它的sendAsBinary为什么不在其中使用它呢?

另外,我还修复了与 file.name / file.fileName 字段相关的问题,并将 this.open 更改为 xhr.open,因为 Chrome 和 Fx 似乎对“this”的解释不同。

我对 js 很陌生,所以我不确定,但这似乎适用于 Fx5、Fx7 和 Chrome:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>cross browser drag and drop file upload example</title>
<script language="javascript" type="text/javascript" src="/js/libs/jquery-1.4.4.min.js"></script>
<script type="text/javascript">
// add the dataTransfer property for use with the native `drop` event
// to capture information about files dropped into the browser window
jQuery.event.props.push("dataTransfer");

$(function() {
    $('#dropzone').bind("drop",function(evnt) {
        evnt.stopPropagation();
        evnt.preventDefault();

        var data = evnt.dataTransfer;
        for (var i = 0; i < data.files.length; i++) {
            var file = data.files[i];
            var fileName;
            if(file.name)
                    fileName = file.name;
                else
                    fileName = file.fileName; 

            var boundary = '------multipartformboundary' + (new Date).getTime();
            var dashdash = '--';
            var crlf     = '\r\n';

            // Build RFC2388 string
            var builder = '';
            var builder2 = '';

            builder += dashdash;
            builder += boundary;
            builder += crlf;

            // generate headers
            builder += 'Content-Disposition: form-data; name="user_file[]"';
            if (fileName) {
                builder += '; filename="' + fileName + '"';
            }
            builder += crlf;

            builder += 'Content-Type: application/octet-stream';
            builder += crlf;
            builder += crlf;

            //
            // binary data string in FileReader's onload (see below)
            //

            builder2 += crlf;

            //write boundary
            builder2 += dashdash;
            builder2 += boundary;
            builder2 += crlf;

            // mark end of the request
            builder2 += dashdash;
            builder2 += boundary;
            builder2 += dashdash;
            builder2 += crlf;


            // setup filereader: read file and send it
            var reader = new FileReader();
            reader.onload = function(evt) {
                var binary = evt.target.result;

                var xhr = new XMLHttpRequest();
                xhr.open("POST", "save.php", true);
                xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=' + boundary);

                //sendAsBinary: deprecated Mozilla only, define NEWsendAsBinary and use it in other browsers
                if(!XMLHttpRequest.prototype.sendAsBinary){
                    XMLHttpRequest.prototype.NEWsendAsBinary = function(datastr) {
                                    function byteValue(x) {
                                return x.charCodeAt(0) & 0xff;
                            }
                            var ords = Array.prototype.map.call(datastr, byteValue);
                            var ui8a = new Uint8Array(ords);
                            xhr.send(ui8a.buffer);
                        }
                        xhr.NEWsendAsBinary(builder+binary+builder2);
                    }
                    else {
                        xhr.sendAsBinary(builder+binary+builder2);
                    }
                };

                //read binary data
                reader.readAsBinaryString(file);
            }
            return false;
        }).bind ("dragover",function(evt) {
            evt.stopPropagation();
            evt.preventDefault();
            $(this).css({
            border: '1px solid #ff0000'
        });
        return false;
    });
});
</script>
</head>
<body>
    <div id="dropzone">
        <p>Drop Files Here</p>
    </div>
</body>
</html>

I don't know the answer why this error occurs, but since Fx supports its sendAsBinary why not use it in it?

Also I made a fix related with fields file.name / file.fileName and changed this.open to xhr.open as Chrome and Fx seemed to interpret "this" there differently.

I'm pretty new to js, so I'm not sure about it, but this seems to work in Fx5, Fx7 and Chrome:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>cross browser drag and drop file upload example</title>
<script language="javascript" type="text/javascript" src="/js/libs/jquery-1.4.4.min.js"></script>
<script type="text/javascript">
// add the dataTransfer property for use with the native `drop` event
// to capture information about files dropped into the browser window
jQuery.event.props.push("dataTransfer");

$(function() {
    $('#dropzone').bind("drop",function(evnt) {
        evnt.stopPropagation();
        evnt.preventDefault();

        var data = evnt.dataTransfer;
        for (var i = 0; i < data.files.length; i++) {
            var file = data.files[i];
            var fileName;
            if(file.name)
                    fileName = file.name;
                else
                    fileName = file.fileName; 

            var boundary = '------multipartformboundary' + (new Date).getTime();
            var dashdash = '--';
            var crlf     = '\r\n';

            // Build RFC2388 string
            var builder = '';
            var builder2 = '';

            builder += dashdash;
            builder += boundary;
            builder += crlf;

            // generate headers
            builder += 'Content-Disposition: form-data; name="user_file[]"';
            if (fileName) {
                builder += '; filename="' + fileName + '"';
            }
            builder += crlf;

            builder += 'Content-Type: application/octet-stream';
            builder += crlf;
            builder += crlf;

            //
            // binary data string in FileReader's onload (see below)
            //

            builder2 += crlf;

            //write boundary
            builder2 += dashdash;
            builder2 += boundary;
            builder2 += crlf;

            // mark end of the request
            builder2 += dashdash;
            builder2 += boundary;
            builder2 += dashdash;
            builder2 += crlf;


            // setup filereader: read file and send it
            var reader = new FileReader();
            reader.onload = function(evt) {
                var binary = evt.target.result;

                var xhr = new XMLHttpRequest();
                xhr.open("POST", "save.php", true);
                xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=' + boundary);

                //sendAsBinary: deprecated Mozilla only, define NEWsendAsBinary and use it in other browsers
                if(!XMLHttpRequest.prototype.sendAsBinary){
                    XMLHttpRequest.prototype.NEWsendAsBinary = function(datastr) {
                                    function byteValue(x) {
                                return x.charCodeAt(0) & 0xff;
                            }
                            var ords = Array.prototype.map.call(datastr, byteValue);
                            var ui8a = new Uint8Array(ords);
                            xhr.send(ui8a.buffer);
                        }
                        xhr.NEWsendAsBinary(builder+binary+builder2);
                    }
                    else {
                        xhr.sendAsBinary(builder+binary+builder2);
                    }
                };

                //read binary data
                reader.readAsBinaryString(file);
            }
            return false;
        }).bind ("dragover",function(evt) {
            evt.stopPropagation();
            evt.preventDefault();
            $(this).css({
            border: '1px solid #ff0000'
        });
        return false;
    });
});
</script>
</head>
<body>
    <div id="dropzone">
        <p>Drop Files Here</p>
    </div>
</body>
</html>
随梦而飞# 2024-12-19 07:47:44

我遇到了类似的问题,最终必须确保输入元素已启用多选,并且我不再使用过时的属性 fileName 和 fileSize。

https://developer.mozilla.org/en/DOM/File

就我而言,我必须修改以下 GWT 文件:

I had a similar issue and ended up having to make sure the input element was multiselect enabled and that I was no longer using the obsolete attributes fileName and fileSize.

https://developer.mozilla.org/en/DOM/File

In my case I had to modify the following GWT file:

http://code.google.com/p/gwt-fileapi/source/browse/trunk/gwt-fileapi/src/com/gwtpro/html5/fileapi/client/file/File.java?r=9

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文