15

次のUnicodeテキストをHTMLでレンダリングすると、ブラウザ(Google Chrome)は、データをサーバーにポストバックするときに何らかの形式のUnicode正規化を実行することがわかります。(おそらくフォームCで)。

しかし、聖書ヘブライ語(בְּרִיךְהוּא)のテキストを使用する場合、ここ(9ページ)で概説されているように、これはテキストを簡単に壊す可能性があります。

ブラウザの自動テキスト正規化を回避する方法はありますか?

私が直面している問題をより詳細に説明するブログ投稿を書きました:http: //blog.hibernatingrhinos.com/12449/would-it-be-possible-to-have-a-web-browser-based-ヘブライ語テキストの編集者

4

3 に答える 3

11

これは、WebKitブラウザ(Chrome、Safari)の機能/バグのようです。フォームデータをNFCに正規化します。これは、特に、連続する結合マークを「正規の」順序に並べ替えることを意味します。これは私にとっては初めてのことであり、このような場合には悪いニュースです。最悪のことは、ブラウザが異なれば動作も異なることです。

テストケースの簡易バージョンを使用するhttp://blog.hibernatingrhinos.com/12449/would-it-be-possible-to-have-a-web-browser-based-editor-for-an-hebrew-text(生データをエコーするだけのサーバーサイドスクリプトを使用して)、ChromeとSafariがU + 05E9 U + 05C1 U + 05B5(SHIN、SHIN DOT、TSERE)のダイアクリティックマークを並べ替えているのに対し、IE、Firefox、Operaはしない。

また、ラテン文字のeを使用​​して簡単なテストを実行した後、分音記号U+0308を組み合わせました。WebKitブラウザーは、NFCの規則に従って、それを単一の文字に変換しますが、他のブラウザーは、文字のペアをそのまま保持します。

これは、2006年以来、意図的な機能のようです。https://bugs.webkit.org/show_bug.cgi?id=8769は、バグ修正の一環としてこれを誇らしげに発表しています!これは、W3Cポリシードキュメントのステータスを説明している可能性があります。現在のバージョンはこの問題でWebKitを重視していますが、他のブラウザベンダーは、「早期正規化」のアイデアに興味がないか、故意に反対しています。</ p>

これを防ぐ方法はないと思います。ただし、ChromeとSafariを使用しないようにユーザーに警告することはできます。単純な問題のケースを含む非表示フィールドを使用して、サーバー側で送信されたかどうかを確認し、送信されていない場合はブラウザーを変更するようにユーザーに指示することもできます。

一般的な正規化ルーチンは明らかに必要な順序をサポートしていないため、サーバー側の順序の修正は簡単ではありません。完全に分解された形式(NFD)に正規化してから、目的に応じて独自のコードを使用して結合マークを並べ替えることができます。おそらくもっと簡単で安全なのは、マークを組み合わせるシーケンスを他のシーケンスに置き換えるアドホック置換ルーチンを実行することだけです。これは、影響を与えたい文字以外の文字には影響を与えないため、より安全ですが、NFDは、特に発音区別符号を使用してラテン文字を分解します。

Unicodeの原則によれば、標準的に同等の文字列(たとえば、連続する発音区別符号の順序のみが異なる)は、同じデータの異なる表現ですが、Unicode文字(コードポイント)のシーケンスとしては異なります。表示が異なることは期待されていませんが、異なる場合があります。一般に、プログラムが違いを生む可能性はありますが、プログラムが標準的に同等の文字列を異なるものとして扱うことを期待するべきではありません。Unicode正規化FAQを参照してください。

FAQエントリは、聖書ヘブライ語の問題がCOMBININGGRAPHEMEJOINERの導入によって解決されたと主張しています。Chromeでの並べ替えはできませんが、不器用な方法であり、レンダリングが混乱する可能性があります(Webブラウザーではそうなります。発音区別符号は、ひどく置き忘れられる可能性があります)。

于 2012-06-25T13:08:51.827 に答える
3

文字列ではなくUint8Arrayを送信することで、文字列の正規化を回避できます。まず、@ Moshevで説明されているように、文字列のUTF-8データをUint8Arrayとして取得します

function utf8AbFromStr(str) {
    var strUtf8 = unescape(encodeURIComponent(str));
    var ab = new Uint8Array(strUtf8.length);
    for (var i = 0; i < strUtf8.length; i++) {
        ab[i] = strUtf8.charCodeAt(i);
    }
    return ab;
}

次に、そのUint8ArrayをプレーンXHRまたはお気に入りのAjaxライブラリでPOSTできます。jQueryを使用している場合は、jQueryがprocessData: falseそれを文字列化しようとして、すべてのハードワークを元に戻さないように指定する必要があることに注意してください。

于 2015-09-16T18:17:15.610 に答える
0

送信する前に、クライアント側でテキストを操作できます。結合子ジョイナーの挿入が機能する場合は、JavaScriptを介して挿入できます。

見つめている点として、これが文字を1文字ずつ取得するJSFiddleです(Safariでテストされており、テキストは正規化されていません):http: //jsfiddle.net/TmtnA/

于 2012-09-05T10:46:46.813 に答える