• 締切済み

CGI文字コードの設定

 CGIにて、日本語の文字列を送信して、次のページでそれを表示する ということを試みています。例えば、 "page A"からリンクで"page B"に飛ぶとします。 --- page A (HTML)--- <a href="http://abc.dom/index.cgi?query=$string">Link</a> そのとき、"page B"の題名を"page A"のリンクの中から取り出すとします。 --- page B (HTML)--- <h1>$string</h1>  そこで、$stringに日本語を入れて送信したいのですが、 送信する前に、エンコードして、 --- page A (CGI)--- $string = "日本語"; # 例えば $string =~ s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg; print "<a href=\"abc.dom?query=$string\">Link</a>"; 受信した後、デコードして、 --- page B (CGI)--- $string =~ tr/+/ /; $string =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg; print "<h1>$string</h1>"; のようにしているのですが、うまく表示してくれません。  カーソルを"Link"に合わせると、ステータスバーには http://abc.dom/index.cgi?query=□u□{□e... このような文字化け?したものが表示されます。(...は続くという意味です。) しかし、アドレスバーには http://abc.dom/index.cgi?query=%93%FA%96%7B%8C%EA と表示され、エンコードがなされていることが分かります。  実際に、クリックしてリンク先を見てみると、 $BF|K\8l (B というようなわけの分からない文字列が表示されます。 ブラウザ表示は『日本語(Shift-JIS)』になっていますが、 色々と設定を変更しても同様にうまく表示されません。  エンコードやデコードをよく理解していないのかもしれませんが、 どなたか私のやっている中のバグをご指摘して頂けないでしょうか。

  • wataj
  • お礼率83% (133/160)
  • CGI
  • 回答数3
  • ありがとう数3

みんなの回答

回答No.3

実際に、組み込みしてみると不具合が出るということですと もう一度、全体的なフロー(流れ)を再点検されてみるといいかもしれません。 ひとつ気になっていたのは、 ttp://abc.dom/index.cgi?query=□u□{□e... と化ける点です。 実はエンコードされてない文字が送られているとか・・ もしくは、エンコードとデコードが逆ではないか?等・・

wataj
質問者

お礼

ちなみに、test.cgiにおいては実験こそうまく行きましたが、 http://127.0.0.1/test.cgi における %95%b6%8e%9a%97%f1 にカーソルを合わせると、 http://127.0.0.1/test.cgi?□¶□□□n というような“文字化け”したものが表示されます。 しかし、この場合は、クリックしたら 文字列 が表示され、うまく行きますが・・。 とりあえず、私のブラウザでは test.htmlにおいて、 <a href="http://127.0.0.1/test.cgi?query=%93%FA%96%7B%8C%EA">日本語</a> という一行のソースを書いたとしても、 カーソルを合わせたステータスバーには 文字化けしたものが入っています。 ちなみに、私が使っているブラウザは I.E.6.0 です。  色々とご指南頂き、ありがとうございました。  そして、せっかく教えて頂いたのに、うまく文字化けを直すことが出来ず、 申し訳ありません。

wataj
質問者

補足

そうなんですよね・・。 ?query=□u□{□e... に直接 ?query=%93%FA%96%7B%8C%EA を打ち込んで試してみても、ステータスバーには ?query=□u□{□e... と表示されてしまうんです。この場合も、 実際にクリックした後のアドレスバーには ?query=%93%FA%96%7B%8C%EA と表示されるんですけどね・・。 ・・分からないことだらけです。 私にとっては。

回答No.2

うーん、このスクリプト、試してみてください。 念のため、ShiftJISコードで保存してください。 Filename:test.cgi ----- #!/usr/bin/perl print "Content-type: text/html\n\n"; if($ENV{QUERY_STRING} eq '') { $str=&encode("文字列"); print << "EOM"; <html><body> <a href="test.cgi?$str">$str</a><br> </body></html> EOM } else { $str=&decode($ENV{QUERY_STRING}); print << "EOM"; <html><body> <a href="test.cgi">$str</a><br> </body></html> EOM } sub decode { my ($s) = @_; $s =~ tr/+/ /; $s =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("C", hex($1))/eg; return $s; } sub encode { my ($encoded) = @_; $encoded =~ s/(\W)/'%' . unpack('H2', $1)/eg; return $encoded; }

wataj
質問者

補足

ご指導ありがとうございます。  ymdaさんのスクリプトを実験しましたところ、うまくいきました。  ただ、どの部分が文字化けに影響しているのかがいまだに掴めません。 エンコードとデコードは同じように実行されているように見えるのですが・・。 どのように私のスクリプトに組み込めばよいのかを教えて頂ければ幸いに存じます。

回答No.1

ためしにこうしてみてください。 $str=&encode("文字列"); $str=&decode($str); sub decode { my ($s) = @_; $s =~ tr/+/ /; $s =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("C", hex($1))/eg; return $s; } sub encode { my ($encoded) = @_; $encoded =~ s/(\W)/'%' . unpack('H2', $1)/eg; return $encoded; }

wataj
質問者

お礼

 投稿ありがとうございました。  先ほど試しましたところ、残念ながら、同じ結果となりました。 コードを見るところ、エンコードとデコードをサブルーチンの中に入れた部分以外に相違点がないように思われるのですが、何か異なるポイントはあったのでしょうか。

関連するQ&A

  • METHOD=GETでパラメータを渡す時に日本語が文字化けする。

    以下のようにMETHOD=GETでCGIスクリプトにパラメータを渡してQUERY_STRINGから読み出す場合、$a_wordが日本語だと文字化けして正しく送れません。 http://~/~/wwwperl.cgi?mode=tophtml&page=$next_line&a_word=$a_word http://~/~/wwwperl.cgi?mode=tophtml&page=10&a_word=テレビ朝日 $a_wordの「テレビ朝日」が「テ・E喞・」となってしまう。 フォームで送ればちゃんと表示されるのですが、ここはどうしてもMETHOD=GETで渡したいのです。 どなたか理由または解決方法を教えていただけると嬉しいのですが・・・ スクリプトはEUCで書いています。Jcode.pmを使用。 エンコード部分はこんな感じです。 sub decode { my $buf; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buf, $ENV{'CONTENT_LENGTH'}); } else { $buf = $ENV{'QUERY_STRING'}; } foreach ( split(/&/, $buf) ) { my ($key, $val) = split(/=/); $key =~ tr/+/ /; $key =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("H2", $1)/eg; $val =~ tr/+/ /; $val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("H2", $1)/eg; Jcode::convert(\$val, 'euc'); $FORM{$key} .= "\0" if (defined($FORM{$key})); $FORM{$key} .= $val; } $mode = $FORM{'mode'}; $page = $FORM{'page'}; $a_word = $FORM{'a_word'}; }

    • ベストアンサー
    • Perl
  • CGIの中で異なるContent-typeのファイルを・・・。

    CGIでの処理で、今 http://xxxx.com/ok.cgi?id=123&pass=abc&page=index.html でindex.html が表示されているとします。 それで、このindex.htmlから別の拡張子のファイルへリンクさせ、ファイルをダウンロードできるようにしたいと思っています。lzh ならURLはこん感じになります。 http://xxxx.com/ok.cgi?id=123&pass=abc&page=sample.lzh  しかし ok.cgi の最後で print "Content-type: text/html\n"; exit; を指定しているのでリンク先へ行ってもindex.htmlは表示されますが、リンク先のファイルは動きません。 どうすればダウンロード出来るようになるでしょうか? なるべくこのok.cgi の外に出したくないのです。  また、この中で、リンク先が隠れるphpを入れたいと考えましたが、phpも同様に機能しません。これもどのようにすればよろしいでしょうか?  どなたかよろしくお願い致します。

    • ベストアンサー
    • Perl
  • CGIが動きません

    GETのbodyにbase64でエンコードされた文字列 typeにMIMEタイプ それをエンコードして出力するものです よろしくお願いします。 以下はソースコードです。 #!/usr/local/bin/perl @querystring = split (/&/,$ENV{'QUERY_STRING'}); foreach $tmp (@querystring) { ($vname,$value) = split (/=/,$tmp); $args{$vname} = &url_decode($value); } sub url_decode($) { my $url_decode_str = shift; $url_decode_str =~ tr/+/ /; $url_decode_str =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg; return $url_decode_str; } print "Content-type:".$args{'type'}."\n\n"; binmode (STDOUT); $out = MIME::Base64::decode_base64($args{'body'}); print $out;

    • ベストアンサー
    • Perl
  • urlエンコード後の文字コードは何?

    $str = "%E3%82%84%E3%81%BE+%E3%81%8B%E3%82%8F"; $str =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("C", hex($1))/eg; こうやってurlエンコードすると、以下のようになります。 「やま+かわ」 1.この「やま+かわ」というのは文字コードは何なんでしょうか? 2.Jcode.pmなどのライブラリを使わずに、utf-8で統一したCGIを書きたいのですが、この文字列をどうすればいいでしょうか。コツを教えてください。 3.あと、+を半角スペースに置換する以外に なにか特別なルールはありますか? 4.参考になるWebページがあれば教えてください。

    • ベストアンサー
    • Perl
  • CGIプログラム 初歩的質問

    http://xxx.ne.jp/xxx.cgi 内設定 --------------------- $word = $ENV{'QUERY_STRING'}; ページに貼ったリンク -------------------------------- <a href="http://xxx.ne.jp/xxx.cgi?http://okwave.net/" target="_blank">http://okwave.net/</a> この場合だと、$word で http://okwave.net/ とCGI側に出てきますが、 <a href="http://xxx.ne.jp/xxx.cgi?無理難題" target="_blank">無理難題</a> と、日本語に変えるとCGI側表示が文字化けします。 何か付け加える必要があるのでしょうか? 検索しますがいまいちはっきりとした答えがありません。 ご教授をよろしくお願いします。

    • ベストアンサー
    • CGI
  • ページの識別をクエリでやらせる意味は?

    ネット上で、以下のようなアドレスをもったサイトを見かけることがあります。 http://www.abc.com/?page_id=company http://www.abc.com/?page_id=product http://www.abc.com/?page_id=support http://www.abc.com/以降のファイル名が省略されていますが、おそらくindex.cgiだかindex.phpだかのサーバーサイドプログラムが置いてあって動作しているのだと思います。クエリpage_idの値を取得し、それによってプログラムで表示するページの内容を変えているのだと思いますが、なぜわざわざこのような方法と使っているのでしょうか?それぞれcompany.htmlまたはcompany/index.htmlのようにhtmlファイルを用意する方が簡単だと思うのですが。phpなどのプログラムはSEOに弱く、SEOを気にするなら文書データであるhtmlデータの方が良いと聞いたこともあります。

  • mod_rewriteの設定方法について教えてください。

    mod_rewriteで下記のようにURLの書き換えの設定を行っているのですが、 実際のURL [A] http://hogehoge.com/index.cgi?a=123&b=abc ↓ アクセスするURL [B] http://hogehoge.com/123/abc/ となるように、下記のように設定を行ったのですが、 --------------------------------------------------------- RewriteEngine on RewriteCond %{HTTP_HOST} ^([^:]+) RewriteRule ^/([^\/]+)/([^\/]*) http://%1/index.cgi?a=$1&b=$2 [L,R] --------------------------------------------------------- 上記の設定を行ったうえで[B]にアクセスすると正しく[A]にアクセスは出来るのですが、ブラウザのアドレス欄は[A]のURLに変換されて表示されます。 これを[B]の表示のままにすることって可能なのでしょうか? もし可能なようでしたらその設定方法を教えていただけないでしょうか。 よろしくお願いいたします。 ApacheバージョンはApache/2.0.52です。

  • CGIでのフォームのデコードについて

    お世話になります。 formで検索結果を表示する際にワードが文字化けしてしまうのでご相談です。 フォームにキーワードをいれ、その結果を返すというページを作成しているのですが、 <form action="search.cgi" method="get">といった形で、GETを利用し検索フォームを作成する際に、URLエンコードはうまくいくのですが、検索キーワードが文字化けをしていまします。 例)イチゴを検索してみると、 URL http://アドレス/search.cgi?mode=meta&t_mode=meta_page&ie=Shift_JIS&oe=Shift_JIS&word=%83C%83%60%83S&hl=ja 検索キーワード 検索結果が「繧、繝√ざ」と表示されてしまう。 そのため検索結果が0となる。 エンコードはうまくいっているが、デコードが不具合を起こしているようなのですが… sub url_decode($) { my $str = shift; $str =~ tr/+/ /; $str =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg; return $str; } どう修正したらよいのかご教授いただけると幸いです。よろしくお願いします。 (文字コードは今回はShift_JISを利用することを前提としています。)

    • 締切済み
    • CGI
  • CGI Perl語で作ったページの文字

    簡潔に質問します。 CGIで作ったページを開くと文字が日本語で表示されないのですが、どうしたら日本語で表示されますでしょうか? 因みに左クリック~エンコード~日本語にしても駄目でした。

  • データをCGIに渡す形式に変換する。

    中に入れ子で別のCGIが入っているCGIを考えました。 <iframe ・・・ action="入れ子.cgi?data1=なんたら&data2=かんたら"></iframe> みたいな感じです。 data1とdata2は親のCGIで考えて入れ子のCGIに渡します。 ところでCGIにマルチバイト文字を渡す場合は、何らかの処理をして  %([a-fA-F0-9][a-fA-F0-9]) の形式に変換されます。 これを元に戻す方法が  =~s/%([a-fA-F0-9][a-fA-F0-9])/pack("H2", $1)/eg; であることは分かったのですが、ならば元の文字列を  %([a-fA-F0-9][a-fA-F0-9]) に変換する方法が  =~s/[^a-fA-F0-9]/unpack("H2", $1)/g; かと思いきや、うまく動きません。 どのように式を書けばいいのでしょうか? #! usr/bin/perl -d use utf8; binmode(STDOUT,'utf8'); our %in=(textfield=>'テスト',submit=>'送信'); foreach(keys %in) { my $unpack=$in{$_}; my $unpack=~s/[^a-fA-F0-9]/unpack("H2", $1)/g; my $pack=$unpack; $pack=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("H2", $1)/eg; print "$_ &nbsp; $in{$_} &nbsp; $unpack &nbsp; $pack <br>\n"; }

    • ベストアンサー
    • Perl

専門家に質問してみよう