Httpプロトコルの符号化

2950 ワード

Get方式で中国語のパラメータを伝達するのは多くの問題があります!うっかりするとサーバーが文字化けして受け取る!したがって,一般的には,できるだけPost手法を用いて中国語パラメータの伝達を実現する.しかし、予想外の場合はGetメソッドを使わざるを得ない場合があります.解決策はいくつかあります.
Javascript(encodeURI/encodeURIComponent関数)を使用してURIまたはパラメータをUTF-8符号化し、サーバ側でを復号する
Getヘッダ格納パラメータを使用せず、エンティティ部分格納パラメータを使用する(Java servletにとっては可能であり、他の場合は知らない.一般的にGetメソッドのHttp通信はヘッダにのみエンティティがないため、このメソッドには限界があり、Javascriptでは実現できない)Postを使用する(前述のように、jsでurlを直接開いてコンテンツをダウンロードするなど、Postを使用できない場合があります)その経緯を詳しく説明します!
どうして中国語が文字化けしますか.
これはHttpプロトコルから始めます.Http通信プロトコルはヘッダ,エンティティの2つの部分に分かれている.エンティティ部分はオプションで、Getメソッドのように必ずしも必要ではありません.Getの要求を返すと,エンティティ部分の符号化はヘッダのcontentの値に基づいて決定される.例:Content-Type:text/html;charset=UTF-8エンティティの符号化をutf-8形式に設定します.
Post方式の要求パラメータはエンティティ部分に置かれている.
Javascriptを使用してPostパラメータを渡す場合、エンティティ部分の符号化は、所在するドキュメントの符号化に基づいて符号化される.
Get方式の要求パラメータはヘッダのurに配置される.
Javascriptを使用してGetパラメータを渡す場合、ヘッダの符号化はASCII文字セットのみをサポートします.ブラウザはURIをエンコードします.
getメソッドでは,要求されたurlの後ろにデータを直列にパラメータとして,urlパッチが完了するとブラウザがurlに対してURI encodeを行い,サーバに送信する.URI encodeのプロセスは、部分的なurlを文字として、ある符号化方式(utf-8、gbkなど、各ブラウザが異なる)に従ってバイナリのバイトコードに符号化し、バイトごとに3文字を含む文字列「%xy」で表し、xyはそのバイトの2ビット16進数表現形式である.また、スペースは「+」に置き換えられます.詳細な手順は、JDKソースコードにおけるURIEncodeクラスの実装を参照することができる.
「各ブラウザのエンコードが異なる」ことがわかり、ユーザーがデフォルトのエンコードを自分で設定できるため、多くの異なる可能性があります.これはなぜIEがfirefox文字化けして、この機械は別の機械が文字化けしてもいい根源です.異なるブラウザがURIの非ASCII文字をどのような符号化を使用して符号化しているかは判断できません(ascII可読文字は符号化されていません)、サーバで自分がどの復号を使用しているかを判断することはできません.さらに残念なことに、異なるサーバにもデフォルトの復号があります.例えば、Tomcatの復号形式はISO-8559-1(server.xmlの修正が可能)である.
より一般的なソリューションを実現するにはどうすればいいですか?
冒頭では3つのソリューションに言及しましたが、2、3つ目はパラメータをエンティティ部分に配置しているので安全で安心しています.この2つのコードはプログラムで簡単に制御できます.しかし、それらには共通の案として使用できない限界があります.だから第1の案が最も実行可能です.
具体的な手順:
ブラウザ側はencodeURIを用いてURIを2回符号化する.
サーバ側はURI decode(UTF-8)を使用して1回復号する(Java:URIDecode.decode(「パラメータ」、「utf-8」)まず、encodeURIとencodeURIComponent関数について説明します.
encodeURIとencodeURIComponentは、文字列をURI encode(utf-8符号化)するものであり、プロセスは前に述べたが、異なる.encodeURIには「!@#$&*()=:/;?+」と符号化されない文字があり、またencodeURIComponentメソッドには「!*()」と符号化されない文字があります.ブラウザのデフォルトURI encodeは、すべてのASCII文字が符号化されないことです.
なぜ2回符号化し、1回復号するのですか?
まず、ブラウザは非ASCII文字のみを符号化するので、encodeURI符号化を2回または1回行った後、ブラウザの符号化は機能しません.では、なぜ2回の符号化を行うのでしょうか.
サーバ側がURIの復号にどのような符号化を使用するかは不明であるためである.もちろん、あなたが使用しているプラットフォームが固定されていると確信しているなら、必要ありません.コードがプラットフォームにまたがるようにするには、考慮する必要があります.これだけでは直接的ではありません(サーバがTomcatであると仮定します):
「中国語」 ==encodeURI==>  ”%E4%B8%AD%E6%96%87″  ==encodeURI(%符号化)=>> ”%25E4%25B8%25AD%25E6%2596%2587″   ==Tomcat復号(ISO-8859-1)=>   ”%E4%B8%AD%E6%96%87″ ==Java decode(UTF-8)==>  ”中国語」
2回のutf-8符号化が行われ、1回のISO-8859-1復号、1回のutf-8復号が見られる.ISO-8859-1とutf-8はいずれもASCII文字セット(%はその1つ)を含んでいるため、文字化けしは発生しない.
jQueryの罠
jQueryでajax操作を行う場合、ブラウザ側で1回だけエンコードし、サーバ側で手動で復号すればよいのはなぜですか?
jQueryはajax操作時にデフォルトで1回符号化されているため:
function add( key, value ){
    s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
};