node.js - HapiJS: Corrupt File Download via Browser - Works via Curl -


i'm struggling issue hapijs 11.1.4 , replying stream serve browser file. resulting download corrupt.

the main endpoint /api/library/export , uses exceljs generate stream containing data xlsx file, i'm replying with.

this endpoint works expected when accessed using curl , no corruption occurs. purely browser i'm having issues with.

code /api/library/export endpoint:

handle(request, reply) {   // invoke xlsx generation , reply   maprecordstoxlsx(xlsxopts).then(stream => {     console.log(stream.length);     return reply(stream)     // .type('application/octet-stream')     // .type('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')     // .header('content-disposition', 'attachment; filename=library-export.xlsx;')     // .header('content-length', stream.length)     // .encoding('binary')     // .encoding(null)   }); } 

as can see, i've tried various combinations of response headers, no avail.

code maprecordstoxlsx:

export function maprecordstoxlsx(opts) {   const workbook = new excel.stream.xlsx.workbookwriter();   workbook.created = new date();   workbook.modified = new date();    // iterate through each set of mappings , records   opts.foreach(({title, mappings, types, records}) => {     // create worksheet current set     const sheet = workbook.addworksheet(title);     // set column headers mapping     const headers = object.keys(mappings);     sheet.columns = headers.map(header => {       return { header, key: mappings[header] };     });      // generate rows each record in current sheet     records.foreach(record => {       const row = {};       headers.foreach(header => {         let value = _.get(record, mappings[header]);         // detect custom types , apply appropriate transformations         if (types[header]) {           switch (types[header]) {           case 'date':             value = new date(date.parse(value)); // exceljs wants date object             break;           default:             break;           }         }         row[mappings[header]] = value;       });       sheet.addrow(row).commit();     });      sheet.commit();   });    return workbook.commit().then(() => {     return workbook.stream.read();   }); } 

and, on receiving side (emberjs):

  exportall() {     const searchstring = this.get('searchstring');     if (searchstring.length > 0) {       this.set('loading', true);       this.get('library').exportall(searchstring)       .then(xlsx => {         this.set('loading', false);         const filename = `library - ${searchstring}.xlsx`;         // hack force download of file         const = document.createelement('a');         document.body.appendchild(a);         a.style = 'display: none';         const blob = new blob([xlsx], {type: 'octet/stream'});         const url = window.url.createobjecturl(blob);         a.href = url;         a.download = filename;         a.click();         window.url.revokeobjecturl(url);         return a.parentnode.removechild(a);       });     }   } 

this.get('library').exportall(searchstring) purely abstraction on ember.$.ajax() resolve/rejects promise.

a comparison of resulting files, browser (left) vs curl (right):

a comparison of resulting files: browser (left) vs curl (right)

the encoding looks wrong can't figure out how happening.

this may me:

http/1.1 200 ok vary: origin,accept-encoding access-control-allow-origin: http://localhost:4200 access-control-expose-headers: www-authenticate,server-authorization content-type: application/octet-stream cache-control: no-cache content-length: 10157 accept-ranges: bytes date: tue, 15 aug 2017 13:49:50 gmt connection: keep-alive 

content-length matches being logged hapijs.


Comments

Popular posts from this blog

PHP and MySQL WP -

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

go - golang pprof for c library code -