2015-10-02 2 views
2

При попытке сохранить каплю (извлеченную с помощью запроса XMLHttpRequestGET, Safari на прошивке 8.4 бросает ошибку:Попытка хранить блобы в IOS Safari 8 бросает DataCloneError

DataCloneError: DOM IDBDatabase Exception 25: The data being stored could 
not be cloned by the internal structured cloning algorithm 

Это случилось с моим кодом, а также этот пример: http://robnyman.github.io/html5demos/indexeddb/

Это линия, которая вызывает мой код (и в приведенном выше примере) на провал:

//This throws the error 
var put = transaction.objectStore("elephants").put(blob, "image"); 

есть ли исправление для этого? Должен ли сначала использовать blob base64 (например, вы должны были использовать WebSQL)?

Моего КОД(работаю в настольном Chrome/Firefox и Chrome/Firefox на Android):

var xhr = new XMLHttpRequest(); 
var blob; 

//Get the Video 
xhr.open("GET", "test.mp4", true); 

//Set as blob 
xhr.responseType = "blob"; 

//Listen for blob 
xhr.addEventListener("load", function() { 
     if (xhr.status === 200) { 
      blob = xhr.response; 

      //Start transaction 
      var transaction = db.transaction(["Videos"], "readwrite"); 

      //IT FAILS HERE 
      var put = transaction.objectStore("Videos").put(blob, "savedvideo"); 

     } 
     else { 
      console.log("ERROR: Unable to download video."); 
     } 
}, false); 

xhr.send(); 

ответ

3

Для некоторых нечетного причины (это ошибка), так же, как IOS Safari 7 в WebSQL , вы не можете хранить BLOB в IndexedDB на iOS Safari 8. Вы должны преобразовать его в base64, а затем он будет хранить без ошибок. (Повторяю, это ошибка)

Таким образом, измените код на этот:

Изменить тип ответа

xhr.responseType = "arraybuffer"; 

Сохранение в базе данных после извлечения из XMLHttpRequest

//We'll make an array of unsigned ints to convert 
var uInt8Array = new Uint8Array(xhr.response); 
var i = uInt8Array.length; 
var binaryString = new Array(i); 
while (i--) 
{ 
    //Convert each to character 
    binaryString[i] = String.fromCharCode(uInt8Array[i]); 
} 

//Make into a string 
var data = binaryString.join(''); 

//Use built in btoa to make it a base64 encoded string 
var base64 = window.btoa(data); 

//Now we can save it 
var transaction = db.transaction(["Videos"], "readwrite"); 
var put = transaction.objectStore("Videos").put(base64, "savedvideo"); 

После извлечения формы IndexedDB, c обратно:

//Convert back to bytes 
var data = atob(event.target.result); 

//Make back into unsigned array 
var asArray = new Uint8Array(data.length); 

for(var i = 0, len = data.length; i < len; ++i) 
{ 
    //Get back as int 
    asArray[i] = data.charCodeAt(i);  
} 

//Make into a blob of proper type 
var blob = new Blob([ asArray.buffer ], {type: "video/mp4"}); 

//Make into object url for video source 
var videoURL = URL.createObjectURL(blob); 
+0

Благодарим вас за то, что нашли время, чтобы узнать это здесь. Вы столкнулись с любыми другими проблемами StackOverflow, которые должны быть связаны здесь? Или проблемы на других сайтах StackExchange? – sideshowbarker

+0

Кроме того, вы знаете, есть ли ошибка Safari/WebKit https://bugs.webkit.org/ для этого? Если нет, пожалуйста, подумайте о повышении. И независимо (если есть уже один открытый или если вы открываете его), было бы неплохо также ссылаться на это отсюда. – sideshowbarker

+0

@sideshowbarker Я создал ошибку в базе данных ошибок Apple, а не webkit, это не проблема WebKit (работает в Chrome до того, как они отключили WebKit). Реализация Safari неверна. Я нашел несколько других старых вопросов от людей, которые, возможно, испытывают одно и то же (не уверен, что их код не существует), но нет ответов. –

Смежные вопросы