• ベストアンサー

メールヘッダのMIMEエンコードについて

今、CGIでメールを送信するフォームを作成しているます。 日本語のsubjectを使う場合はMIMEエンコードをしなければいけないと聞いてmime_plsというライブラリで試してみたのですが、受信した結果、「1月1日」→「1 月 1 日」のように半角数字と全角文字の間にスペースが入ってしまいます。 これはどうしたらよいのでしょうか。 コードは以下のように書いています。 $mon = substr($reserveday, 4, 2); $day = substr($reserveday, 6, 2); $subject = sprintf("%d月%d日の件について", $mon, $day); &Jcode::convert(\$subject, 'jis'); $from = &mimeencode($from); $to = &mimeencode($to); $subject = &mimeencode($subject); $contents .= "本文"; &Jcode::convert(\$contents, 'jis'); my $send_buf=''; $send_buf .= "From: $from\n"; $send_buf .= "To: $to\n"; $send_buf .= "Subject: $subject\n"; $send_buf .= "Content-Type: text/plain; charset=iso-2022-jp\n"; $send_buf .= "Content-Transfer-Encoding: 7bit\n"; $send_buf .= "Mime-Version: 1.0\n"; $send_buf .= "\n"; $send_buf .= $contents; # メール送信 open(MAIL,"| $sendmail -t -i -f $from"); print MAIL $send_buf; close(MAIL); よろしくお願いします。

  • Perl
  • 回答数4
  • ありがとう数6

質問者が選んだベストアンサー

  • ベストアンサー
  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.2

ヘッダのMIMEエンコードでは、 「エンコードされた文字列」と「エンコードされていない生の文字列」の間には空白を入れなければなりません。 そのため、MIMEエンコードされていない「1」とMIMEエンコードされた「月」の間にスペースが入ってしまうのです。 元々、MIMEは英語圏で決められた規格であり、英語などでは単語と単語の間に空白が入るのが当たり前なため、「空白無しに文字列が続く」ような状況が想定されていないという、いわば MIME の規格の欠陥です。 規格にきちんと従うかぎりは、「1月1日」という文字列をそのままMIMEエンコードできないのです。 対処方法ですが、 ・規格にきちんと従うなら、半角スペースが入るのを許容するしかありません。 ・規格無視で、見た目重視なら、半角文字も含めてヘッダの全ての文字列をエンコードしてしまうという方法があります。 後者の方法は、手軽にやるなら、 > $subject = &mimeencode($subject); の代わりに > $subject = "=?ISO-2022-JP?B?".&MIME::base64encode($subject)."?="; でいけます。 ただし、メールヘッダは76文字以内で改行することが推奨されていますが、その処理をしてませんので、長い文字列を入れると文字列長の点でも規格外になります。 なお、mimeencode を使う場合は、この関数自身が改行処理をしてくれますが、その文字数の計算が間違えないように、 mimeencodeに渡す引数には、「Subject:」や「To:」込みのヘッダ行をまるごと渡したほうがいいでしょう。

moriyamajoe
質問者

お礼

とても詳しい解説ありがとうございます。MIME規格についてたいへん勉強になりました。 今回の場合、見た目を重視したいので、後者の方法を試してみようと思います。 ちなみに参考のためにお聞きしたいのですが、Outlook Express, Becky!Ver2, gmailなど私が使ったことのあるメールソフトでは半角と全角の間にスペースが 入るというのを見たことがありません。 これは後者の方法で規格を無視していると考えてもいいのでしょうか。 ご存知であれば教えていただけないでしょうか。

その他の回答 (3)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

mime_pls でできるかどうか分かりませんしどのくらいの人がやる気になるかもわかりませんが, あくまで理論的には「1」もエンコードすれば回避できます. つまり, 例えば 「1月1日」 =?US-ASCII?Q?1?= =?ISO-2022-JP?B?GyRCN24bKEI=?= =?US-ASCII?Q?1?= =?ISO-2022-JP?B?GyRCRnwbKEI=?= 「1月 1日」 =?US-ASCII?Q?1?= =?ISO-2022-JP?B?GyRCN24bKEI=?= =?US-ASCII?Q?_1?= =?ISO-2022-JP?B?GyRCRnwbKEI=?= とすれば区別できます (Q と B が混在しているという指摘は本質ではないので却下). 厳密に言うと MIME の規格はこの狭間を「完全に無視しているわけではない」のですが, なぜか中途半端にしか決めていないという不思議な状況.

moriyamajoe
質問者

お礼

回答ありがとうございます。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

ちょっと確認してほしいことがあるのですが, 「1月1日」と「1月 1日」(後者は 2個目の「1」の前に空白が入っている) のそれぞれをエンコードした結果の文字列はどうなっているでしょうか? これらが一緒だとすると, 「MIME の仕様の狭間」に落っこちている可能性があります.

moriyamajoe
質問者

お礼

試してみました。 「1月1日」 1 =?ISO-2022-JP?B?GyRCN24bKEI=?= 1 =?ISO-2022-JP?B?GyRCRnwbKEI=?= 「1月 1日」 1 =?ISO-2022-JP?B?GyRCN24bKEI=?= 1 =?ISO-2022-JP?B?GyRCRnwbKEI=?= まったく同じ内容でした。 これが「MIME の仕様の狭間」というもので、mtaka2さんもおっしゃっていたものですね。 理由がわかりました。ありがとうございます。

  • zxcv0000
  • ベストアンサー率56% (111/196)
回答No.1

「そんな事は気にしない」が許容できるならベストだと思います。 許容できないとなると、「空白の挿入」の責任が送信側の「mime_plsというライブラリ」にあるのか、それとも受信者が使用するメールソフトにあるのか調べたり、どのメールソフトでどうなるかを確認したりと大変でしょう。 もし Encode.pm を使用できるなら、 encode('MIME-Header-ISO_2022_JP', $text); も試されてはいかがでしょうか。

moriyamajoe
質問者

お礼

気にしないってことができればいいんですけどね~(笑) メールクライアントはBecky!Ver2とgmailで確認していて、両方で同じ現象が起こるので、スクリプト側の原因と推測しているのです。 あとサーバのperlが5.6なのでEncode.pmは使えないようです。

関連するQ&A

  • MIME::Lite ActivePerlでエラー

    MIME::Lite ActivePerlでエラー Linuxで動いたメール送信プログラムをActivePerlで動かしたところ下記のエラーになりました。 SMTP Failed to connect to mail server: Bad file descriptor 該当行はMIME::Liteでメールを送信する部分でした。 return($message->send); Windows(Activeperl)上で動かす場合なにか特別な設定が必要なのでしょうか? 以下、プログラムの抜粋です。 use Jcode; use MIME::Lite; # 値の設定 sub testmail{ $subject = jcode($subject)->mime_encode(); $data = jcode($data)->jis; $message = MIME::Lite->new( From => $mailfrom, To => $mailto, Subject => $subject, Type => 'multipart/related' ); $message->attach( Type => 'text/html; charser="iso-2022-jp"', Data => $data ); foreach(@cid){ $message->attach( Type => 'image/gif', Id => $_, Path => "./$_" ); } return($message->send); }

    • ベストアンサー
    • Perl
  • sendmail実行時のエラー

    受け渡されたパラメーターをセットしてsendmailを実行すると「Premature end of script headers:」というエラーになります。 試しにパラメーターを直セットしてsendmailすると、文字化けはしますが送信はされました。 メールでなく、ファイルに出力してみたところ、 From: " =?ISO-2022-JP?B?GyRCJDUkRiQ1JEYbKEI=?= "<xxxx@xxxx.ne.jp> Subject: =?ISO-2022-JP?B?GyRCIXo7cU5BQEE1YRsoQg==?= この2つだけが文字化けしていて、本文は大丈夫でした。 ソースは以下の通りです。 require './jcode.pl'; # MIMEエンコードライブラリを使う $mimew = './mimew.pl'; ・・・・・略 # MIMEエンコード if (-e $mimew) { require $mimew; $subject = &mimeencode($mail_sub); $from = &mimeencode("From: \"$in{'cname'}\" <$in{'mail'}>"); } else { $subject = $mail_sub; &jcode'convert(*subject,'jis'); $from = "From: $in{'mail'}"; } ・・・・パラメータのコンバート&jcode'convert(データ, 'jis'); ・・・・メール本文($mail_body)のセット $err = 0; open(MAIL,"| $sendmail -t") || $err = 1; print MAIL "To: $mailto\n"; print MAIL $from, "\n"; print MAIL "Subject: $subject\n"; print MAIL "Content-Type: text/plain; charset=ISO-2022-JP\n"; print MAIL "Content-Transfer-Encoding: 7bit\n\n"; print MAIL "$mail_body\n"; close(MAIL); 文字化けもですが、まずはエラーを解消するにはどうしたらいいでしょうか。教えて下さい。お願いします。

  • sendmailのFROMに日本語を使う

    CGIからsedmailを呼び出してメールを送信しています。 その時に差出人の部分の日本語が文字化けしてしまいます。 そこで&jcode'convertでjisに変えたのですが、今度は CGIがサーバーエラーになってしまいます。 どうすればよいでしょうか。 スクリプトはこんな感じです。 ----------------------------------------------- $from = '両国'; $subject = 'テスト'; &jcode'convert(*from, 'jis'); &jcode'convert(*subject, 'jis'); &jcode'convert(*msg, 'jis'); $errno = 1 unless open(MAIL, "| /usr/lib/sendmail -t"); return 0 if $errno; print MAIL "To: $MailTo\n"; print MAIL "From: $from\n"; print MAIL "Subject: $subject\n"; print MAIL "Content-Type: text/plain;\n\n"; print MAIL "$msg\n"; $errno = 2 unless close(MAIL); return 0 if $errno;

    • ベストアンサー
    • Perl
  • SUBJECTのエンコードをすると文字化ける

    SUBJECTに40byte以上を設定して、エンコードをすると文字化けが発生します。 なぜ文字化けが発生するのか分かりません。 もしご存知の方がいれば、アドバイスをよろしくお願い致します。 SUBJECTに設定されている文字は 1234567890123456789012345678901234567890 です。 実際に届くメールのSUBJECTは 123456789012345678901234567 弦葦桶患況弦 です。 関数の内容は以下の通りです。 sub MailSend {  my $head = $_[0];  my $body = $_[1];  my $flgMime = $_[2]; #エンコード判定フラグ my $in_return = 0; my $rc;  my $cmdMail = "/usr/lib/sendmail -t";  &Jcode::convert( $$head{ "SUBJECT" }, "jis" ); foreach( @{$body} ){ &Jcode::convert( $_, "jis" ) }; if( $flgMime ){ $$head{ "SUBJECT" } = MIME::mimeencode($$head{ "SUBJECT" }); } $rc = open( OUTMAIL, "| $cmdMail" ) ; if($rc) { print OUTMAIL "MIME-Version: 1.0\n"; print OUTMAIL "Content-Type: text/plain; charset=\"iso-2022-jp\"\n"; print OUTMAIL "Content-Transfer-Encoding: 7bit\n"; print OUTMAIL "From: $$head{ $DefaultValue::FROM }\n"; print OUTMAIL "To: $$head{ $DefaultValue::TO }\n"; print OUTMAIL "Cc: $$head{ $DefaultValue::CC }\n"; print OUTMAIL "Bcc: $$head{ $DefaultValue::BCC }\n"; print OUTMAIL "Subject: $$head{ $DefaultValue::SUBJECT }\n"; print OUTMAIL "\n"; foreach( @{$body} ){ print OUTMAIL $_."\n" }; print OUTMAIL ".\n"; close( OUTMAIL ); foreach( @{$body} ){ print OUTMAIL $_."\n" }; print OUTMAIL ".\n"; close( OUTMAIL ); } else{ $in_return = 1; } return $in_return; }

  • ホームページから意見を送るsendmailのcgiスクリプト

    表題のようなスクリプトを使っているのですが、 普通は特に問題ないのですが、「http://」などから始まる URLのみを書き込んで送ると、空メール(何も記載されない)となって 届いてしまいます。どこがおかしいのかわかりません。 以下のようなスクリプトです。 @pairs = split(/&/,$buffer); foreach $pair (@pairs) { ($name,$value) = split(/=/,$pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; $name =~ tr/+/ /; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; &jcode'convert(*name,'sjis'); &jcode'convert(*value,'sjis'); if ($name eq 'to') { $to = $value; } if ($name eq 'from') { $from = $value; } if ($name eq 'subject') { $subject = $value; } if ($name eq 'body') { $body = $value; } } # cheack if ($from eq "") { $from = "unknown\@."; } if ($from eq " ") { $from = "unknown\@."; } # send mail &jcode'convert(*from,'jis'); &jcode'convert(*subject,'jis'); &jcode'convert(*body,'jis'); if (!(open(MAIL,"| $sendmail -t"))) { &error('システムエラー','メールの送信に失敗しました。'); } print MAIL "To: $to\n"; print MAIL "From: $from\n"; print MAIL "Subject: $subject\n"; print MAIL "Content-Type: text/plain; charset=iso-2022-jp\n"; print MAIL "$body\n"; close(MAIL); # view html &jcode'convert(*from,'sjis'); &jcode'convert(*subject,'sjis'); &jcode'convert(*body,'sjis'); $body =~ s/\r\n/\r/g; $body =~ s/\n/\r/g; $body =~ s/\r/<BR>/g;

    • ベストアンサー
    • CGI
  • メールを文字化けしないようにしたい

    次のようにメールを送信しようとしています。 Fedora CoreはUTF-8なので、jcode.plでJISに変換しようとしています。 require "jcode.pl"; $subject = "テストメール"; $data = "これはテストメールです。"; &jcode::convert(\$subject,'jis'); &jcode::convert(\$data,'jis'); @str = "subject:$subject\n\n"); push (@str, "$data\n.\n"); これがなぜかうまくいきません。メーラーの文字コードをutf8にすると正常に表示されます。 使い方が違うのかと思ったので、次のように変えてみたところ、エラーになりました。 &jcode::convert(\$subject,'utf8','jis'); また、先頭にuse utf8;を付けてみたところ、送信できたものの文字化けが余計ひどくなりました。 インターネットで検索したり本を読んでみたりしても、よくわかりませんでした。 どうやったらJISに変換できるのでしょうか。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • Perlにて、sendmailを使用するがエラー…

    はじめまして、初めて質問させて頂きます、ぷりんと申します。 早速ですが、質問です。 私はPerlにてメールフォームの作成に勤しんでいるのですが、どうしても500エラーが出てしまいます。 サーバーはレンタルサーバーのロリポップを使用しております。 私が不思議に思うのは、メール自体は送信されますが、ページには500エラーと表示されてしまうことです。 以下は実際のコードです。(全文)(一部変更有(メール宛先部分)) #!/usr/bin/perl require "../mimew.pl"; require "../jcode.pl"; $sendmail = '/usr/lib/sendmail'; $to = "hogemoge\@gmail.com"; $from = "test\@test.tet"; $subject = "題"; $body = "メール本文"; # 本文をJISコードへ変換 &jcode'convert(*body,'jis'); # 標題をJISコードへ変換してMIME エンコード &jcode'convert(*subject,'jis'); $subject = mimeencode($subject); open(MAIL,"| $sendmail -t"); print MAIL "To: $to\n"; print MAIL "From: $from\n"; print MAIL "Subject: $subject\n"; print MAIL "\n"; print MAIL "$body\n"; close(MAIL); exit(0); と記述し、こちらのcgiファイルはパーミッション700(ロリポップさんが700で動くので)、アスキーコードでアップロード。 mimew.plとjcode.plどちらも一つ上のフォルダにあります。(パーミッションは644) 以上です。 当方初心者ですので、いろいろ試したのですが、どちらが悪いのか見当つきません・・。 簡単な検索をしましたが、Syntax Errorは見つかりませんでした。 また、いろいろなサイトを参考にしたり、検索したりしましたが、問題解決には至りませんでした。 おそらく初歩的なミスだとは思います・・。 こちらの問題に関してお詳しい方、どうかお手を差し伸べていただけないでしょうか。 何卒、よろしくお願い申し上げます。

    • ベストアンサー
    • Perl
  • メール送信のFromアドレスについて

    始めまして。 taki2といいます。 Perlのメール送信で使用するFromアドレスで分からない 事がありますので、アドバイスをよろしくお願いします。 -内容- Fromをtaki@xxx.comと設定してメールを送信した場合、実際届くメールのFromには taki@xxx.com と、表示されます。 しかし、Fromを"taki@xxx.com"と設定した場合 実際届くメールのFromは "taki@xxx.com"@xxx.com と、表示されます。 ""をつけるとどうやら""の中がアカウントと認識されるみたいです。 これを""があっても@xxx.comを設定せずにしたいのですが、どうすればよいのでしょうか? ちなみにメール送信しているプログラムは以下の通りです。 sub MailSend {  my $head = $_[0];  my $body = $_[1];  my $flgMime = $_[2]; #エンコード判定フラグ my $in_return = 0; my $rc;  #メールコマンド  my $cmdMail = "/usr/lib/sendmail -t";  #文字コード変換  ##件名  &Jcode::convert( $$head{ "SUBJECT" }, "jis" ); ##本文 foreach( @{$body} ){ &Jcode::convert( $_, "jis" ) }; #ヘッダのMIMEエンコード if( $flgMime ){ $$head{ "SUBJECT" } = MIME::mimeencode($$head{ "SUBJECT" }); } #メール送信 $rc = open( OUTMAIL, "| $cmdMail" ) ; if($rc) { print OUTMAIL "From: $$head{ "FROM" }\n"; print OUTMAIL "To: $$head{ "TO" }\n"; print OUTMAIL "Cc: $$head{ "CC" }\n"; print OUTMAIL "Bcc: $$head{ "BCC" }\n"; print OUTMAIL "Subject: $$head{ "SUBJECT" }\n"; print OUTMAIL "\n"; foreach( @{$body} ){ print OUTMAIL $_."\n" }; print OUTMAIL ".\n"; close( OUTMAIL ); } else{ $in_return = 1; } return $in_return; }

    • ベストアンサー
    • Perl
  • アンケートフォームに機能の付け加え。

    ホームページ上で、訪問者からアンケートを採れるsendmailを使用した CGIを設置しています。ここに、訪問者から簡単な素材を提供して頂けるよう 以下のようなスクリプトに、小さなファイル(gif画像など)を 添付して送れるように機能を付け足したいです。 どうすればいいか、困っています。どうすればよいでしょうか? @pairs = split(/&/,$buffer); foreach $pair (@pairs) { ($name,$value) = split(/=/,$pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; $name =~ tr/+/ /; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; &jcode'convert(*name,'sjis'); &jcode'convert(*value,'sjis'); if ($name eq 'to') { $to = $value; } if ($name eq 'from') { $from = $value; } if ($name eq 'subject') { $subject = $value; } if ($name eq 'body') { $body = $value; } } # cheack if ($from eq "") { $from = "unknown\@."; } if ($from eq " ") { $from = "unknown\@."; } # send mail &jcode'convert(*from,'jis'); &jcode'convert(*subject,'jis'); &jcode'convert(*body,'jis'); if (!(open(MAIL,"| $sendmail -t"))) { &error('システムエラー','メールの送信に失敗しました。'); } print MAIL "To: $to\n"; print MAIL "From: $from\n"; print MAIL "Subject: $subject\n"; print MAIL "Content-Type: text/plain; charset=iso-2022-jp\n\n"; print MAIL "$body\n"; close(MAIL); # view html &jcode'convert(*from,'sjis'); &jcode'convert(*subject,'sjis'); &jcode'convert(*body,'sjis'); $body =~ s/\r\n/\r/g; $body =~ s/\n/\r/g; $body =~ s/\r/<BR>/g;

    • 締切済み
    • CGI
  • sendmailで送信すると、迷惑メールになります

    フォームに入力された内容をperlでsendmailを使って送信すると、ウイルス対策ソフトの判定で、迷惑メールに入ってしまいます。 ▼プログラム $subject = 'テストメール'; $msg = "------------------------------------------------------------------ [名前] $name [住所] $address ------------------------------------------------------------------"; # subjectをBase64エンコード jcode::convert(\$subject, 'euc'); jcode::convert(\$subject, 'jis', 'euc', 'z'); $subject = '=?ISO-2022-JP?B?' . encode_base64($subject, '') . '?='; # 本文をJISに変換 jcode::convert(\$msg, 'jis'); &mail($to_mail, $from_mail, $subject, $msg); ▼サブルーチン sub mail{ my($to_mail, $from_mail, $subject, $msg) = @_; # sendmailによるメール発信 my $sendmail = '/usr/lib/sendmail'; # sendmailパス open(MAIL,"| $sendmail -t") || &error("メール送信に失敗しました"); print MAIL "To: $to_mail\n"; print MAIL "From: $from_mail\n"; print MAIL "Subject: $subject\n"; print MAIL "X-Mailer: Mail Form Sendmail\n"; print MAIL "Content-Transfer-Encoding: 7bit\n"; print MAIL "Content-type: text/plain; charset=\"iso-2022-jp\"\n"; print MAIL "MIME-Version: 1.0\n\n"; print MAIL "$msg"; close(MAIL); } print MAIL "Content-type: text/plain; charset=\"iso-2022-jp\"\n"; を print MAIL "Content-type: text/plain;\n"; にすれば迷惑メールにならずに済むのですが、一部の利用者(特にMacユーザー)で、送信されたメールが文字化けしているようですので、何とかcharsetの指定も入れたいと思っています。 上記のプログラムで、おかしいところがあるでしょうか? どうか、ご教示いただけますよう、よろしくお願いします。

    • ベストアンサー
    • CGI

専門家に質問してみよう