
今、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);
よろしくお願いします。
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:」込みのヘッダ行をまるごと渡したほうがいいでしょう。
とても詳しい解説ありがとうございます。MIME規格についてたいへん勉強になりました。
今回の場合、見た目を重視したいので、後者の方法を試してみようと思います。
ちなみに参考のためにお聞きしたいのですが、Outlook Express, Becky!Ver2,
gmailなど私が使ったことのあるメールソフトでは半角と全角の間にスペースが
入るというのを見たことがありません。
これは後者の方法で規格を無視していると考えてもいいのでしょうか。
ご存知であれば教えていただけないでしょうか。
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 の規格はこの狭間を「完全に無視しているわけではない」のですが, なぜか中途半端にしか決めていないという不思議な状況.
No.3
- 回答日時:
ちょっと確認してほしいことがあるのですが, 「1月1日」と「1月 1日」(後者は 2個目の「1」の前に空白が入っている) のそれぞれをエンコードした結果の文字列はどうなっているでしょうか?
これらが一緒だとすると, 「MIME の仕様の狭間」に落っこちている可能性があります.
試してみました。
「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さんもおっしゃっていたものですね。
理由がわかりました。ありがとうございます。
No.1
- 回答日時:
「そんな事は気にしない」が許容できるならベストだと思います。
許容できないとなると、「空白の挿入」の責任が送信側の「mime_plsというライブラリ」にあるのか、それとも受信者が使用するメールソフトにあるのか調べたり、どのメールソフトでどうなるかを確認したりと大変でしょう。
もし Encode.pm を使用できるなら、
encode('MIME-Header-ISO_2022_JP', $text);
も試されてはいかがでしょうか。
気にしないってことができればいいんですけどね~(笑)
メールクライアントはBecky!Ver2とgmailで確認していて、両方で同じ現象が起こるので、スクリプト側の原因と推測しているのです。
あとサーバのperlが5.6なのでEncode.pmは使えないようです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) エクセル VBA メール本文に指定セルに記載されているURLをリンクとして記載する方法 8 2022/08/08 07:50
- その他(SNS・コミュニケーションサービス) 自分のpcがハッキングされたようなメールが来たのですがどうすればいいですか? 4 2022/10/02 16:14
- 戦争・テロ・デモ ウクライナ、メル友に五千円要求されてさ 1 2022/04/02 09:38
- その他(プログラミング・Web制作) laravel 本番環境でメールが送れません。 1 2023/02/17 17:57
- Excel(エクセル) 2つのVBAを一緒にしたら機能しなくなりました(エクセル) 7 2022/06/02 12:41
- 英語 海外から返金 1 2022/06/30 08:20
- Visual Basic(VBA) 【追加】ファイルを閉じてダイアログで保存した時だけ処理の実行をする 3 2022/03/23 15:43
- Visual Basic(VBA) このマクロの説明文を教えてほしいです。 1 2023/01/12 09:17
- 英語 その手紙はおじへ送った方がいい。 You should send the letter to you 3 2023/05/11 00:20
- PHP Content-Typeが機能していない? 2 2022/07/17 11:10
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
GDBでデバッグするとき文字列の...
-
リフェラーで弾く方法について
-
Perl(Windows)の文法について
-
splitの逆の処理
-
日本語文字列の指定長(byte)切出し
-
パイソンエラーについて
-
ワイルドカード処理
-
VBA like演算子について
-
CSVファイルの中で、「 , 」カ...
-
エクセルで数値を全角文字(カ...
-
WORDで改ページすると時々グレ...
-
C#で、テキストボックスの入力...
-
正規表現で、特定の文字列を含...
-
住宅にカナを入力する際に丁目...
-
IEからEdgeへの移行に伴うIMEの...
-
EXCELからCSVにすると余計なカ...
-
word差し込み印刷 半角カタカ...
-
VB2005のTextBoxでカン...
-
Excel VBAでPDFファイルをMicro...
-
CString から LPCTSTRの型に変換
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
パイソンエラーについて
-
cryptの使用方法
-
Malformed UTF-8 character
-
perlでの判定がうまくいきません
-
VBA split(文字列, ★) ★←複数...
-
メールヘッダのMIMEエンコード...
-
perlを使用しての特定行抽出に...
-
Perlで Right関数に近い処理を...
-
GDBでデバッグするとき文字列の...
-
文字列検索(例えばindex関数)...
-
改行コードから改行コードまで...
-
文字列と数字を含むセルから数...
-
日本語文字列の指定長(byte)切出し
-
PERLのSHIFT_JISの振る舞いにつ...
-
Perlの正規表現でマッチする範...
-
splitの逆の処理
-
数値の抽出方法がわからず困っ...
-
ファイルから文字列を読み出し...
-
環境変数のHTTP_REFERERのチェック
-
Perl(Windows)の文法について
おすすめ情報