2013-07-26 22 views
26

Tôi cần thêm dấu thứ tự byte UTF-8 vào dữ liệu văn bản được tạo ở phía máy khách. Làm thế nào để làm điều đó?Thêm UTF-8 BOM vào chuỗi/Blob

Sử dụng new Blob(['\xEF\xBB\xBF' + content]) sản lượng '"my data"', tất nhiên.

Không làm '\uBBEF\x22BF' hoạt động (với '\x22' == '"' là ký tự tiếp theo trong content).

Có thể thêm UTF-8 BOM vào JavaScript vào văn bản được tạo không?

Có, tôi thực sự cần có UTF-8 BOM trong trường hợp này.

Trả lời

73

Prepend \ufeff vào chuỗi. Xem http://msdn.microsoft.com/en-us/library/ie/2yfce773(v=vs.94).aspx

Xem cuộc thảo luận giữa @jeff-fischer@caseyfor details on UTF-8 and UTF-16 và BOM. Điều thực sự làm cho công việc trên là chuỗi \ufeff luôn được sử dụng để đại diện cho BOM, bất kể UTF-8 hoặc UTF-16 đang được sử dụng.

Xem p.36 trong The Unicode Standard 5.0, Chapter 2 để biết giải thích chi tiết. Một trích dẫn từ trang đó

Mục trật tự endian cho UTF-8 trong bảng 2-4 được đánh dấu N/A vì UTF-8 đơn vị mã 8 bit về kích thước, và các vấn đề máy thông thường của endian đơn đặt hàng cho các đơn vị mã lớn hơn không áp dụng. Thứ tự được sắp xếp theo thứ tự của các byte không được khởi động từ thứ tự được xác định theo dạng mã hóa UTF- 8 . Việc sử dụng BOM không bắt buộc hoặc không được đề xuất cho UTF-8, nhưng có thể gặp phải trong các ngữ cảnh mà dữ liệu UTF-8 là được chuyển đổi từ các dạng mã hóa khác sử dụng BOM hoặc trong đó BOM là được sử dụng làm chữ ký UTF-8 .

+1

Tuyệt vời. Cảm ơn bạn. – MMarriott

+0

Dude ... vâng. Điều này hoạt động hoàn hảo. Cảm ơn! Có rất nhiều câu trả lời sai/không hoạt động trên các câu hỏi khác. – KyleFarris

+0

Điều này không phù hợp với tôi. – Moss

7

Tôi đang chỉnh sửa câu trả lời gốc. Câu trả lời trên thực sự đòi hỏi phải xây dựng vì đây là một giải pháp phức tạp của Node.js.

Câu trả lời ngắn gọn là, có, mã này hoạt động.

Câu trả lời dài là, không, FEFF không phải là dấu thứ tự byte cho utf-8. Rõ ràng nút đã lấy một số loại phím tắt để viết mã hóa trong các tệp. FEFF là mã hóa UTF16 Little Endian có thể được nhìn thấy trong bài viết wikipedia của Byte Order Mark và cũng có thể được xem trong một trình soạn thảo văn bản nhị phân sau khi đã viết tệp. Tôi đã xác minh đây là trường hợp.

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

Rõ ràng, Node.js sử dụng \ ufeff để biểu thị bất kỳ số lượng mã hóa. Nó lấy dấu \ ufeff và chuyển nó thành dấu thứ tự byte đúng dựa trên tham số tùy chọn thứ 3 của writeFile. Tham số thứ 3 bạn vượt qua trong chuỗi mã hóa. Node.JS lấy chuỗi mã hóa này và chuyển đổi mã hóa byte cố định thành một trong bất kỳ dấu thứ tự byte mã hóa thực tế nào.

UTF-8 Ví dụ:

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 Ví dụ:

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

Vì vậy, như bạn có thể thấy thông báo \ ufeff chỉ đơn giản là một dấu hiệu nêu bất kỳ số lượng kết quả mã hóa. Các mã hóa thực tế mà làm cho nó vào tập tin là trực tiếp phụ thuộc vào tùy chọn mã hóa được chỉ định. Điểm đánh dấu được sử dụng trong chuỗi thực sự không liên quan đến những gì được ghi vào tệp.

Tôi nghi ngờ rằng lý do đằng sau điều này là vì họ chọn không viết các dấu thứ tự byte và dấu 3 byte cho UTF-8 không được mã hóa dễ dàng vào chuỗi javascript được ghi vào đĩa. Vì vậy, họ đã sử dụng UTF16LE BOM làm dấu vị trí trong chuỗi được thay thế tại thời gian ghi.

+2

Vâng, nếu bạn nhìn vào dấu thứ tự byte và những gì tôi đã nói ban đầu, nó đúng. Dấu thứ tự byte FEFF không phải là dấu thứ tự byte cho UTF-8 như bạn đã nêu trong câu hỏi của mình. Câu trả lời ban đầu dường như đã vấp phải câu trả lời đúng hoặc ít nhất là không giải thích chút nào. Lý do duy nhất họ đã làm đúng là vì các tùy chọn mã hóa mặc định là utf-8. Không phải vì dấu thứ tự byte mà chúng cung cấp thực sự là một dấu thứ tự byte UTF-8. –

+0

Nếu bạn có thể thay đổi câu trả lời của tôi thành +1, điều đó thật tuyệt. –

+0

lol, tốt, một người khác sẽ muốn thực sự biết cách hoạt động của nó. Kể từ khi câu trả lời ban đầu không mô tả lý do tại sao một UTF16LE BOM kỳ diệu hoạt động. Một người nào đó trong tương lai sẽ muốn thực sự hiểu những gì đang xảy ra. –

3

tôi đã cùng một vấn đề và đây là giải pháp tôi đến với:

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

Sử dụng Uint8Array ngăn trình duyệt từ chuyển đổi những byte thành chuỗi (thử nghiệm trên Chrome và Firefox).

Bạn nên thay thế text/plain bằng loại MIME bạn muốn.

Các vấn đề liên quan