, Исходный файл: // не разрешен Access-Control-Allow-Origin.

я проблема с BlobBuilder (Chrome11). Я пытаюсь получить изображение с сервера с запросом XHR. Затем я пытаюсь сохранить его на локальном компьютере с помощью BlobBuilder / FileWriter. Каждый пример в интернете посвящен работе с типом text / plain mime, и эти примеры работают нормально. Но когда я пытаюсь записать двоичные данные, полученные с помощью XHR, размер файла становится примерно в 1,5-2 раза больше исходного размера файла. И его нельзя просмотреть в Picasa / Eye Of Gnome.

var xhr = new XMLHttpRequest();
var photoOrigUrl = 'http://www.google.ru/images/nav_logo72.png';
xhr.open('GET', photoOrigUrl, true);
xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) {
        var contentType = xhr.getResponseHeader('Content-type');

        fsLink.root.getFile('nav_logo72.png', {'create': true}, function(fileEntry) {
            fileEntry.createWriter(function(fileWriter) {
                var BlobBuilderObj = new (window.BlobBuilder || window.WebKitBlobBuilder)();
                BlobBuilderObj.append(xhr.responseText);

                fileWriter.write(BlobBuilderObj.getBlob(contentType));
            }, function(resultError) {
                console.log('writing file to file system failed (   code ' + resultError.code + ')');
            });
        });
    }
}

xhr.send();

fsLink существует, это расширение.

 Greg24 сент. 2012 г., 19:13
Спасибо за вопрос, ответы очень помогли моему проекту!

Ответы на вопрос(5)

Решение Вопроса

Проблема в том, чтоBlobBuilder.append(xhr.responseText) обнаруживает свой аргумент в виде строки UTF-8, которая возвращает XHR, а не двоичные данные, каковы они на самом деле. Есть несколько хитростей, чтобы BlobBuilder считывал его как двоичные данные вместо строковых:

var xhr = new XMLHttpRequest();
var photoOrigUrl = 'http://www.google.ru/images/nav_logo72.png';
xhr.open('GET', photoOrigUrl, true);

// CHANGE 1: This stops the browser from parsing the data as UTF-8:
xhr.overrideMimeType('text/plain; charset=x-user-defined');

xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) {
        var contentType = xhr.getResponseHeader('Content-type');

        fsLink.root.getFile('nav_logo72.png', {'create': true}, function(fileEntry) {
            fileEntry.createWriter(function(fileWriter) {

                // CHANGE 2: convert string object into a binary object
                var byteArray = new Uint8Array(xhr.response.length);
                for (var i = 0; i < xhr.response.length; i++) {
                    byteArray[i] = xhr.response.charCodeAt(i) & 0xff;
                }

                var BlobBuilderObj = new (window.BlobBuilder || window.WebKitBlobBuilder)();

                // CHANGE 3: Pass the BlobBuilder an ArrayBuffer instead of a string
                BlobBuilderObj.append(byteArray.buffer);

                // CHANGE 4: not sure if it's needed, but keep only the necessary
                // part of the Internet Media Type string
                fileWriter.write(BlobBuilderObj.getBlob(contentType.split(";")[0]));
            }, function(resultError) {
                console.log('writing file to file system failed (   code ' + resultError.code + ')');
            });
        });
    }
}

xhr.send();

Это дало мне файл с той же длины, что иxhr.getResponseHeader('Content-Length') предполагает, что это должно было быть.

 Dmitrii Sorin30 мая 2011 г., 07:38
Stolve, ты МУЖЧИНА !!! Вы сделали мой день! Большое спасибо Вам! Единственное, что я не понимаю, это переопределение mimetype с помощью этого «text / plain; charset = x-user -определенный». Я всегда думал, что здесь можно указать необходимый тип mimetype ответа, но почему мы должны указывать здесь «text / plain»?
 Stoive30 мая 2011 г., 08:20
Рад помочь :). Эта строка просто говорит браузеру не делать ничего умного с данными, возвращаемыми запросом - в противном случае он всегда будет пытаться превратить его в текст с кодировкой текста текущей страницы (я думаю ...). Возможно, историческая вещь, так как XHR ранее использовался только для «text / xml» или «application / xml», по предположению.
 Dmitrii Sorin30 мая 2011 г., 10:19
ааа ладно благодарю вас
 Stoive30 мая 2011 г., 05:59
Кроме того, не забывайте принимать ответы, когда вы думаете, что они верны;)
 ebidel04 сент. 2011 г., 02:29
Не использоватьxhr.overrideMimeType(...), Это хакерство и есть лучшие способы добиться того же. Смотрите мой ответ ниже по использованиюArrayBuffer.

что Stoive на месте, но я хочу отметить, что вместо BlobBuilder теперь доступен конструктор Blob, который сделает свое дело

 var b = new Blob([byteArray.buffer], {'type': 'application/type'});

, что это больше соответствует текущим стандартам. Большое спасибо Stoive, очень полезно.

 thedethfox19 дек. 2013 г., 09:43
+ 1.BlobBuilde дублирован, теперь Blob следует использовать во всех случаях.

http://www.google.ru/images/nav_logo72.png, Исходный файл: // не разрешен Access-Control-Allow-Origin.

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://www.google.ru/images/nav_logo72.png', true);
xhr.responseType = 'blob';

xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) {
        // xhr.responseBlob is needed blob data
    }
}

xhr.send();

Единственное разочарование в том, что это все еще ошибка в Chrome:http://code.google.com/p/chromium/issues/detail?id=52486

Вы можете использоватьxhr.responseType='arraybuffer' хотя:

BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;

var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'arraybuffer';

xhr.onload = function(e) {
  if (this.status == 200) {
    var bb = new BlobBuilder();
    bb.append(this.response); // Note: not xhr.responseText

    var blob = bb.getBlob('image/png');
    ...
  }
};

xhr.send();
 Shanimal17 окт. 2012 г., 15:41
LOL, вы знаете это, ссылка на ваш блогhtml5rocks.com/en/tutorials/file/dndfiles
 Shanimal17 окт. 2012 г., 15:39
+1 за шаг в правильном направлении. Похоже, что BlobBuilder устарел, Chrome просит меня использовать window.Blob.

Ваш ответ на вопрос