Ошибка XHR.send в Firefox 7/8, но не в FF6 / Chrome: 0x80460001 (NS_ERROR_CANNOT_CONVERT_DATA) - PullRequest
1 голос
/ 27 октября 2011

У меня проблемы со скриптом загрузки файла перетаскивания в Firefox 7/8.Я написал базовый скрипт для загрузки файлов, помещенных в DropZone HTML-документа, в серверный скрипт «save.php».полный HTML, включая JavaScript, можно найти ниже.серверная часть не является проблемой, и поэтому я ее пропустил (save.php).

Я искал и пробовал все, но теперь я действительно застрял.скрипт запускается в Firefox 6, а также в Chrome без каких-либо ошибок JavaScript, когда я отбрасываю файл для загрузки (более того, файл правильно сохраняется на сервере, вызывающем save.php).но в ff7 / 8 я получаю следующую ошибку в консоли 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>

Ответы [ 2 ]

0 голосов
/ 15 декабря 2011

У меня была похожая проблема, и в итоге мне пришлось убедиться, что для входного элемента включен множественный выбор, и что я больше не использую устаревшие атрибуты fileName и fileSize.

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

В моем случае мне пришлось изменить следующий файл GWT:

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

0 голосов
/ 28 октября 2011

Я не знаю ответа, почему возникает эта ошибка, но поскольку 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>
...