77

クライアント側で生成されたテキスト データに UTF-8 バイト オーダー マークを追加する必要があります。それ、どうやったら出来るの?

もちろん、new Blob(['\xEF\xBB\xBF' + content])yieldsを使用します。'"my data"'

どちらも機能しませんでした'\uBBEF\x22BF'('\x22' == '"'の次の文字であるためcontent)。

JavaScript で UTF-8 BOM を生成されたテキストの先頭に追加することは可能ですか?

はい、この場合、本当に UTF-8 BOM が必要です。

4

4 に答える 4

161

文字列の先頭\ufeffに追加します。http://msdn.microsoft.com/en-us/library/ie/2yfce773(v=vs.94).aspxを参照してください。

UTF-8 と UTF-16および BOM の詳細については、 @jeff-fischer@casey の間の議論を参照してください。上記を実際に機能させるのは、使用されている UTF-8 または UTF-16 に関係なく、文字列が常に BOM を表すために使用されることです。\ufeff

詳細な説明については、The Unicode Standard 5.0、Chapter 2 のp.36 を参照してください。そのページからの引用

表 2-4 の UTF-8 のエンディアン順エントリは N/A とマークされています。これは、UTF-8 コード単位のサイズが 8 ビットであり、より大きなコード単位のエンディアン順に関する通常のマシンの問題が適用されないためです。バイトのシリアル化された順序は、UTF-8 エンコード形式で定義された順序から逸脱してはなりません。BOM の使用は、UTF-8 では必須でも推奨でもありませんが、BOM を使用する他のエンコード形式から UTF-8 データが変換されるコンテキスト、または BOM が UTF-8 署名として使用されるコンテキストで発生する可能性があります。

于 2013-07-26T10:51:20.003 に答える
35

私は同じ問題を抱えていましたが、これが私が思いついた解決策です:

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

を使用Uint8Arrayすると、ブラウザーはこれらのバイトを文字列に変換できなくなります (Chrome と Firefox でテスト済み)。

text/plain目的の MIME タイプに置き換える必要があります。

于 2016-12-28T13:25:54.730 に答える
21

元の回答を編集しています。上記の回答は、Node.js による複雑なソリューションであるため、詳細な説明が必要です。

短い答えは、はい、このコードは機能します。

長い答えは、いいえ、FEFF は utf-8 のバイト オーダー マークではありません。どうやら node は、ファイル内にエンコーディングを書き込むための何らかのショートカットを使用したようです。FEFF は UTF16 リトル エンディアン エンコーディングであり、バイト オーダー マーク ウィキペディアの記事で見ることができ、ファイルを書き込んだ後にバイナリ テキスト エディターで表示することもできます。であることを確認しました。

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

どうやら、Node.JS は \ufeff を使用して任意の数の encoding を示します。\ufeff マーカーを受け取り、writeFile の 3 番目のオプション パラメータに基づいて正しいバイト オーダー マークに変換します。エンコーディング文字列で渡す 3 番目のパラメーター。Node.JS はこのエンコーディング文字列を受け取り、\ufeff 固定バイト エンコーディングを実際のエンコーディングのバイト オーダー マークのいずれかに変換します。

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 リトル エンディアンの例:

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

ご覧のとおり、 \ufeff は、結果として得られるエンコーディングの数を示す単なるマーカーです。ファイルを作成する実際のエンコーディングは、指定されたエンコーディング オプションに直接依存します。文字列内で使用されるマーカーは、ファイルに書き込まれるものとはまったく関係ありません。

この背後にある理由は、バイトオーダーマークを書き込まないことを選択したためであり、UTF-8 の 3 バイトマークは、ディスクに書き込まれる JavaScript 文字列に簡単にエンコードされないためだと思われます。そのため、書き込み時に置換される文字列内のプレースホルダー マークとして UTF16LE BOM を使用しました。

于 2015-01-16T00:46:05.043 に答える