简体   繁体   中英

Writing binary data from a Nodejs buffer to a blob on Meteor client

I'm trying to create a CSV file that will be saved with UTF-16LE encoding on the server and then pass the result to the client. This is what I do, in Coffeescript:

Meteor.methods {
    iconv: (data, from="UTF-8", to="UTF-16LE") ->
        Iconv = Meteor.require('iconv').Iconv
        iconv = new Iconv(from, to)
        res = iconv.convert(data) 
        res
}

Now if I write the file from the server with the line

fs.writeFileSync('/tmp/test.csv', res)

the file is correctly generated. However, I would like to avoid creating a file on the server and save it directly on the client (using the filesaver library ). The sample client code looks like this:

exportToCsv = (data="tête", filename) ->
    callback = (err, res) ->
        blob = new Blob([res], {type:'text/csv;charset=UTF-16LE'})
        saveAs(blob, filename)
    Meteor.call('iconv', data, callback)

As you can see, the data I'm testing with is a simple string with a special character (the 'ê'). My problem is that I cannot pass the nodejs buffer to the client. It is automatically serialised into:

Object {0: 116, 1: 0, 2: 234, 3: 0, 4: 116, 5: 0, 6: 101, 7: 0}

instead of the buffer output that I get on the server:

<Buffer 74 00 ea 00 74 00 65 00>

The problem is not so much the conversion from hexadecimal to decimal, I know I can convert back to hexadecimal using something Number(116).toString(16) . But how do I write this data as binary in the blob?

OK so in the end it turned out that I was almost there. The only thing I needed to do for the data to be saved correctly in the Blob was to get the data as an array of numbers from the server (through the toJSON() method) and then to create a Uint8Array on the client before saving it to a file blob through the blob.

So on the server:

Meteor.methods {
    iconv: (data, from="UTF-8", to="UTF-16LE") ->
        Iconv = Meteor.require('iconv').Iconv
        iconv = new Iconv(from, to)
        res = iconv.convert(data) 
        res
}

And on the client:

exportToCsv = (data="tête", filename) ->
    callback = (err, res) ->
        byteArray = new Uint8Array(res)
        blob = new Blob([byteArray], {type:'text/csv'})
        saveAs(blob, filename)
    Meteor.call('iconv', data, callback)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM