2016-04-14 3 views
1

Ich arbeite mit ServiceWorker in Chrome und benutze postMessage, um zwischen der Webseite und Servicearbeiter zu kommunizieren. Die Kommunikation umfasst das Anfordern und Empfangen von Dateidaten (gespeichert als Blob).Wie man einen Serviceworker Response Body ReadableByteStream als Blob über PostMessage zurückgibt?

Lassen Sie uns sagen, ich bin ein Blob wie diese zu speichern:

// 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 
      }); 
     }); 

Diese speichert die Datei in Ordnung und ich kann (Fetch verwenden) es abzurufen richtig, anstatt sie aus dem Netzwerk anfordert. Aber wenn ich die match() Methode wie folgt:

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.' 
      } 
      }); 
     } 
     }); 

Ich erhalte eine ReadableByteStream im response.body und bin stecken mit ihm nicht zu wissen, wie Sie den Inhalt zu extrahieren und Pass es zurück über postMessage.

Ich versuche gerade clone() die Antwort als pro this article, weil nur die vollständige Antwort über postmessage Rückkehr wird fehlschlagen, werfen DataCloneError: Fehler auf postmessage Message auszuführen, die ich bin auch nicht eine Menge Informationen zu finden.

Wenn ich klonen, kann ich rufen Sie mich an ein neues Blob geben Blob, die ich dann wieder passieren kann, aber die nur undefiniert zurück, wenn zu lesen versuchen, (?):

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

Wenn Sie sich selbst ausprobieren möchten :

die Datei in Serviceworker zu speichern, das in seiner Inspektor Konsole ausführen:

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()} 
     }); 
    }); 

abzurufen:

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); 
    }) 

Frage: Irgendwelche Tipps, wie ReadableByteStream zu handhaben und extrahieren es Inhalt/MIME-Typ als Blob so kann ich es zurück über postmessage passieren? Vielen Dank!

Antwort

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); 

Das ist, weil Sie nicht readAsText(my_blob) richtig verwenden. Sie müssen einen Rückruf in der onload-Eigenschaft des Dateireaders anfügen und ein Versprechen lösen, wenn der Rückruf aufgerufen wird. Ich meine, statt:

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

Verwendung:

.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!

Um seinen MIME-Typ extrahieren können Sie einfach lesen Sie das Attribut type aus dem Blob-Objekt.

.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

guter Punkt. Das hat funktioniert, und ich hole den Inhalt raus, nach dem ich gesucht habe.Das einzige Problem, das ich habe, ist, dass der MIME-Typ korrekt als Header für meinen * match() * -Aufruf zurückgegeben wird, aber ich kann ihn nicht in den * blob() * -Aufruf übergeben, daher werde ich mit einem lesbaren Blob enden Sie, aber fehlende Mime-Typ-Erklärung. für eine andere Frage. Danke fürs Helfen – frequent

Verwandte Themen