メールのContent-Header, Content-Body の仕様(RFCのピックアップまとめ)

世界中で標準となっているeメール仕様(SMTPプロトコル仕様)はRFC822などのRFCドキュメントです。
原本を読めばすべて書かれているのですが、全部読むのは大変なのでピックアップしてまとめてみました。

続きを読む メールのContent-Header, Content-Body の仕様(RFCのピックアップまとめ)

Outlook Express で Multipart/Related したときの望ましくない挙動

– ドキュメント整理(2004-06)
– Multipart/Related でも、直接の呼び出しが実行中のメールに存在しない場合には添付ファイル扱いになる(A HREF=”CID:〜”ではだめ)。
– HTML同士の Related で<A>や<Iframe>を使おうとしても無理。やはり添付ファイル扱いに。

PHP でメールするときの注意等

– 過去に書いたドキュメントを整理するため、整形してコピペ。内容は多分 2004-06 くらいのもの。
– mail関数と、そのラッパーであるmb_send_mail関数があるが、後者はオプションのヘッダ指定に無関係に、自動的に

MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: 7bit

という3つのヘッダを挿入する(Content-Typeを明示的に指定していてもなお)。
– mail関数のデフォルトのヘッダーは
mail(‘foo@yyy.zz’,’title’,’message’);
として送信した場合、

Return-Path: <anonymous@local.host>
Delivered-To: foo@yyy.zz
Received: (qmail xxxxx invoked from network); 2 Apr 2004 15:13:40 +0900
Received: from unknown (HELO local.host) (xxx.xxx.xxx.xxx)
  by pcxxx.xxx.xxx.xxx.in-addr.foo with SMTP; 2 Apr 2004 15:13:40 +0900
Received: (qmail xxxxx invoked by uid 80); 2 Apr 2004 15:13:40 +0900
Date: 2 Apr 2004 15:13:40 +0900
Message-ID: <20040402061340.11671.qmail@local.host>
From: anonymous@local.host
To: foo@yyy.zz
Subject: title
 
message
 

のようになる。(Received:はもちろんmail関数がつけたものではない)
– MIME-Versionフィールドを指定する場合、第四引数でヘッダ指定する場合に改行は\r\nや直接の改行(SJISの場合CRLFになる)ではなく\nでなければならない。(MIME-Version:1.0を宣言した行以降は\rも\nも1つの行として認識されるため。
– PHPでHTMLメールを送るごく簡単な例)

sAddHeader = “MIME-Version: 1.0\n”
.”Content-Type: multipart/alternative;\n”
.”boundary=\”—-=_NextPart_000_0024_01C418A2.AA46C5F0\”\n”;
$sMessage = “This is a multi-part message in MIME format.”
.”\n\n——=_NextPart_000_0024_01C418A2.AA46C5F0\n”
.”Content-Type: text/plain; charset=ISO-2022-JP\n”
.”Content-Transfer-Encoding: 7bit\n\n”
.”プレーンテキストメールです\n”
.”\n\n——=_NextPart_000_0024_01C418A2.AA46C5F0\n”
.”Content-Type: text/html; charset=ISO-2022-JP\n”
.”Content-Transfer-Encoding: 7bit\n\n”
.”<font color=’red’>HTMLメールです。あ</font>いう<b>えお</b>\n”
.”\n\n——=_NextPart_000_0024_01C418A2.AA46C5F0–\n”;
//送信先メールアドレス等。
$sMailAddress = ‘foo@xxx.zz’;
$sTitle = ‘タイトル’;
if(mail($sMailAddress,$sTitle,$sMessage,$sAddHeader))
echo “sent successfully!\n”;
else
echo “sent failure”;

プラグインや国際化で動作がおかしいときに状態をクリーンにする

eclipse.exe -clean

みたく -clean オプションを付けて Eclipse IDE を起動すると、クリーンアップされて状態が直ったりする。何かあったときに一度だけやればいい。
3.0.x の日本語化周りで、一部しか日本語化されなかった場合などに有効。

Java Applet で JavaScript コードを実行する

import java.applet.Applet;
import netscape.javascript.JSObject;
 
public class jstest extends Applet{
public void start(){
JSObject js = JSObject.getWindow(this);
js.eval(“alert(‘Hello, world!!’)”);
}
}

JavaScript を Java Applet にしてサイズ圧縮をうたい文句にしているソフトより。これなら JavaScript 上で Zip 圧縮/解凍して eval したほうがいい(jar って zip だし、肝心の JavaScript は Java コードのリテラルなので *.class に生で書かれているし)。

ブラウザの JavaScript バージョンチェック

<http://members.at.infoseek.co.jp/sig1/jscript/js-vercheck.html>
– JavaScript バージョンチェック

<SCRIPT LANGUAGE=”JavaScript1.0″><!–
j=”1.0″;
–></SCRIPT>
 .. snip ..
<SCRIPT LANGUAGE=”JavaScript2.0″><!–
j=”2.0″;
//–></SCRIPT>
.. snip ..
<SCRIPT LANGUAGE=”JavaScript1.0″><!–
document.write(“Javascript “+j+” に対応しています。”);
//–></SCRIPT>

というように, <script> の language 属性を使って判別してる。このサイトでは LiveScript, VBScript もチェック対象としているが、VBScript のチェックを JavaScript の文で行おうとしてエラーになっている。IE6 は JavaScript 1.3, Firefox1.0(Gecko/20050318) は JavaScript 1.5 までに対応していた。

[JavaScript][ActionScript] ブロック({ … }) ではスコープの限定ができない

一時変数のスコープを絞るのに { … } をよく使うが、ECMAScript (ActionScript/JavaScript 共通) だと物理的には意味をなさなくなる。例えば、次の文はエラーにはならない:

{var t=”NG”;} alert(t);

ブロックがスコープを持つなら、t は alert() を呼ぶ時点では存在しないためエラーになるべきだが、実際は NG と表示されてしまう。(Firefox 1.0, IE6, Flash MX 2004 で確認)
 
これは制御構文でも同じで、例えば、

for(var i; i < 10; i++){ var n = i; }

は、for 文の終了後に

i = 10; n = 9;

が入ったままになる。スコープを切りたい場合は、その部分だけ関数を使う等するしかなさそう。個人的に、リファクタリングの準備のために頻繁にスコープを切るのでこれは不便だなぁ..
ECMAScript では関数スコープであることを宣言するときのみ var 宣言は意味を成しているよう。
 

簡易タイマー

例えば 1 分後にアラートを鳴らすには次のようにすればよい。
– Windows なら sleep というコマンドを使えるようにしてコマンドプロンプトで

sleep 60 && echo <Ctrl-G>

  • UNIX 系(bash, sh)なら

sleep 60 && printf “\a”

 
追記:
(2006-05-10) sleep が Windows 標準で存在しないことに気づき訂正.

static ファクトリメソッドの落とし穴

Effective Java より、static ファクトリメソッドで Foo.getInstance() みたくするのがいい、とあったが、何も考えずやってると継承周りで混乱を招く。

class Parent {
public static Parent getInstance(){ return new Parent(); }
}
class Child extends Parent {}

このとき、Child.getInstance(); は Child インスタンスではなく(スーパークラスで定義されている getInstance() を使うため) Parent インスタンスを生成してしまう。
 
Effective Java の例にきっちり書かれているとおり、

class Parent {
private Parent(){ }
public static Parent getInstance(){ return new Parent(); }
}

とか class final Parent とかして継承を禁止するのが妥当な解決方法(拡張にはコンポジションを使う)。
それが嫌なら static ファクトリメソッドの公開をやめて普通にコンストラクタを公開する。
 
あるいは、継承を行うクライアントが、確実に public static Child getInstance() を定義してくれることを信じるか。