2016-04-14 4 views
1

Я работаю с ServiceWorker в Chrome и использую postMessage для связи между веб-страницей и serviceworker. Коммуникация включает в себя запрос и получение файлов данных (хранимых как Blob).Как вернуть тело ответа Serviceworker ReadableByteStream как Blob через PostMessage?

Допустим, я хранения Blob, как это:

// param.name = "http://foo.css", 
// param.content = new Blob(
// ["span%2C%20div%20%7Bborder%3A%201px%20solid%20red%20!important%3B%7D"], 
// {type: "text/css"} 
//) 

caches.open(CURRENT_CACHE) 
    .then(function(cache) { 
     request = new Request(param.name, {mode: 'no-cors'}), 
     response = new Response(param.content); 
     cache.put(request, response) 
     .then(function() { 
      event.ports[0].postMessage({ 
      error: null 
      }); 
     }); 

Это сохраняет файл все в порядке и я могу использовать выборки(), чтобы получить его правильно вместо запроса его от сети. Но если я использую матч() метод следующим образом:

caches.open(CURRENT_CACHE) 
    .then(function(cache) { 
    return cache.match(param.name) 
     .then(function(response) { 
     return response.clone().blob(); 
     }) 
     .then(function (converted_response) { 
     if (converted_response) { 
      event.ports[0].postMessage({ 
      error: null, 
      data: converted_response 
      }); 
     } else { 
      event.ports[0].postMessage({ 
      error: { 
       'status': 404, 
       'message': 'Item not found in cache.' 
      } 
      }); 
     } 
     }); 

Я получения ReadableByteStream в response.body и я застрял с ним, не зная, как извлечь содержимое и пропуск он возвращается через postMessage.

Я в настоящее время пытается клон() ответ согласно this article, потому что только что вернулся полный ответ через PostMessage потерпит неудачу, бросая DataCloneError: Не удалось выполнить PostMessage на MessagePort, который я также не нахождение много информации.

Если я клонировать, я могу назвать блоб дает мне новую Blob, который я могу затем передать обратно но только возвращение неопределенными при попытке чтения (?):

var r = new FileReader() 
return r.readAsText(my_blob); 

Если вы хотите попробовать себя :

Чтобы сохранить файл в ServiceWorker, запустите в его инспектор консоли:

caches.keys() 
    .then(function (list) {return caches.open(list[0])}) 
    .then(function (cache) 
     request = new Request("http://foo.css", {mode: 'no-cors'}), 
     response = new Response(new Blob(
     ["span%2C%20div%20%7Bborder%3A%201px%20solid%20red%20!important%3B%7D"], 
     {type: "text/css"} 
    )); 
     cache.put(request, response) 
     .then(function() { 
      event.ports[0].postMessage({ 
      error: null 
      }); 
     }); 
    }) 
    .catch(function(error) { 
     event.ports[0].postMessage({ 
     error: {'message': error.toString()} 
     }); 
    }); 

Чтобы получить:

caches.keys() 
    .then(function (list) {return caches.open(list[0])}) 
    .then(function (cache) {return cache.match("http://foo.css")}) 
    .then(function(answer) { 
    console.log(answer.body); 
    var b = response.body; 
    return answer.clone().blob(); 
    }) 
    .then(function (x) { 
     console.log(x); 
     var r = new FileReader(); 
     return r.readAsText(x) 
    }) 
    .then(function (y) { 
    console.log("DONE"); 
    // undefined 
    console.log(y); 
    }) 

Вопрос: Любые советы, как обращаться с ReadableByteStream и извлечь его содержимое/мим-типа, как Blob, так что я могу передать его обратно через PostMessage? Благодаря!

ответ

3

If I clone, I can call blob giving me a new(?) Blob, which I can then pass back but which only return undefined when trying to read:

var r = new FileReader() 
return r.readAsText(my_blob); 

Это потому, что вы не используете readAsText(my_blob) должным образом. Вы должны приложить обратный вызов в свойстве onload устройства чтения файлов и решить обещание при вызове обратного вызова. Я имею в виду, вместо того, чтобы:

.then(function (x) { 
    console.log(x); 
    var r = new FileReader(); 
    return r.readAsText(x) 
}) 

Использование:

.then(function (x) { 
    return new Promise(function (resolve) { 
    var r = new FileReader(); 
    r.onload = resolve; 
    r.readAsText(x); 
    }); 
}) 

Question: Any tips how to handle ReadableByteStream and extract it's content/mime-type as Blob so I can pass it back over postMessage? Thanks!

Чтобы извлечь его тип пантомимы вы можете просто прочитать атрибут type от объекта BLOB.

.then(function (x) { 
    console.log(x.type); // <-- the mime type 
    return new Promise(function (resolve) { 
    var r = new FileReader(); 
    r.onload = resolve; 
    r.readAsText(x); 
    }); 
}) 
+0

приятный пункт. это сработало, и я получаю контент, который я искал.Только проблема, с которой я столкнулся, - это корректный mime-тип, возвращаемый как заголовок в моем вызове * match() *, но я не могу передать его в вызов * blob() *, поэтому я заканчиваю читаемым блобом благодаря вы, но пропустите объявление типа mime. для другого вопроса. Спасибо за помощь – frequent

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