javascript utf-8 blob fileapi byte-order-mark

javascript - Agregando UTF-8 BOM a cadena/Blob



fileapi byte-order-mark (3)

Estoy editando mi respuesta original. La respuesta anterior realmente requiere una explicación, ya que esta es una solución compleja de Node.js.

La respuesta corta es, sí, este código funciona.

La respuesta larga es, no, FEFF no es la marca de orden de bytes para utf-8. Aparentemente, node tomó algún tipo de atajo para escribir codificaciones dentro de archivos. FEFF es la codificación UTF16 Little Endian que se puede ver en el artículo de la wikipedia de Byte Order Mark y también se puede ver en un editor de texto binario después de haber escrito el archivo. He verificado que este es el caso.

http://en.wikipedia.org/wiki/Byte_order_mark#Representations_of_byte_order_marks_by_encoding

Aparentemente, Node.JS usa / ufeff para indicar cualquier número de codificación . Toma el marcador / ufeff y lo convierte en la marca de orden de bytes correcta basada en el tercer parámetro de opciones de writeFile. El tercer parámetro que pasa en la cadena de codificación. Node.JS toma esta cadena de codificación y convierte la codificación de byte fijo / ufeff en cualquiera de las marcas de orden de bytes de la codificación real.

Ejemplo de UTF-8:

fs.writeFile(someFilename, ''/ufeff'' + html, { encoding: ''utf8'' }, function(err) { /* The actual byte order mark written to the file is EF BB BF */ }

UTF-16 Little Endian Ejemplo:

fs.writeFile(someFilename, ''/ufeff'' + html, { encoding: ''utf16le'' }, function(err) { /* The actual byte order mark written to the file is FF FE */ }

Entonces, como puede ver, / ufeff es simplemente un marcador que indica cualquier número de codificaciones resultantes. La codificación real que lo convierte en el archivo depende directamente de la opción de codificación especificada. El marcador utilizado dentro de la cadena es realmente irrelevante para lo que se escribe en el archivo.

Sospecho que el razonamiento detrás de esto se debe a que optaron por no escribir marcas de orden de bytes y la marca de 3 bytes para UTF-8 no se codifica fácilmente en la cadena de javascript para escribir en el disco. Por lo tanto, utilizaron el UTF16LE BOM como un marcador de posición dentro de la cadena que se sustituye en el momento de la escritura.

Necesito agregar una marca de orden de bytes UTF-8 a los datos de texto generados en el lado del cliente. ¿Cómo puedo hacer eso?

El uso de un new Blob([''/xEF/xBB/xBF'' + content]) produce ''"my data"'' , por supuesto.

Tampoco funcionó ''/uBBEF/x22BF'' (siendo ''/x22'' == ''"'' el siguiente carácter en el content ).

¿Es posible anteponer la lista de materiales UTF-8 en JavaScript a un texto generado?

Sí, realmente necesito la lista de materiales UTF-8 en este caso.


Tuve el mismo problema y esta es la solución que se me ocurrió:

var blob = new Blob([ new Uint8Array([0xEF, 0xBB, 0xBF]), // UTF-8 BOM "Text", ... // Remaining data ], { type: "text/plain;charset=utf-8" });

El uso de Uint8Array evita que el navegador convierta esos bytes en una cadena (probado en Chrome y Firefox).

Debes reemplazar text/plain con tu tipo MIME deseado.


/ufeff a la cadena. Consulte http://msdn.microsoft.com/en-us/library/ie/2yfce773(v=vs.94).aspx

Consulte la discusión entre @jeff-fischer y @casey para obtener detalles sobre UTF-8 y UTF-16 y la lista de materiales. Lo que realmente hace que funcione lo anterior es que la cadena /ufeff siempre se utiliza para representar la lista de materiales, independientemente de UTF-8 o UTF-16 que se esté utilizando.

Consulte la p.36 en The Unicode Standard 5.0, Capítulo 2 para obtener una explicación detallada. Una cita de esa pagina

La entrada de orden endian para UTF-8 en la Tabla 2-4 está marcada como N / A porque las unidades de código UTF-8 tienen un tamaño de 8 bits, y no se aplican los problemas habituales de la máquina de orden endian para unidades de código más grandes. El orden serializado de los bytes no debe apartarse del orden definido por la forma de codificación UTF-8. El uso de una lista de materiales no es necesario ni recomendado para UTF-8, pero puede encontrarse en contextos donde los datos de UTF-8 se convierten de otras formas de codificación que usan una lista de materiales o donde la lista de materiales se usa como una firma UTF-8.