SymRealWinOpenとか

 ときどき自分のサイトのソースに見覚えのないJavaScriptのコード(下記のもの)が挿入されているという質問をする人がいます。

<script language="JavaScript">
<!--

function SymError()
{
  return true;
}

window.onerror = SymError;

var SymRealWinOpen = window.open;

function SymWinOpen(url, name, attributes)
{
  return (new Object());
}

window.open = SymWinOpen;
//-->
</script>
<SCRIPT language="JavaScript">
<!--

window.open = SymRealWinOpen;

//-->
</SCRIPT>

 ソースに自分で記述したわけではないのになぜかこのようなソースが入っているという不可思議な現象に、ウイルスに感染しているのではないかと心配する人までいます。

 実はこのコードを挿入している犯人はNorton Internet Securityの広告ブロックです。ポップアップ広告はかなり嫌われていますが、このコード挿入の目的はそれを抑制することのようです。どうやらページを読み込む際自動的に挿入されているらしく、見たこともないソースがあるとトラブルになることも。

 ソースに見られる"Sym"はNorton Internet Securityの製造元であるSymantec社の頭文字ですね。

 少しこのJavaScriptについて説明を入れることにします。

 まず次の部分ですが、エラーが発生した際のイベントハンドラであるwindow.onerrorにtrueを返す関数のSymErrorを指定することで、エラーの発生を回避する意味を持っています。実際にはポップアップブロッカーの妨害で開いてもいないウィンドウを操作しようとすれば当然エラーが発生しますが、おそらくこれを回避するための記述であると推測されます。

function SymError()
{
  return true; // trueを返す
}

window.onerror = SymError; // エラー発生時にSymError関数の内容が実行される

 そして次のコード。これはまずwindow.open関数と同じ動作をする関数SymRealWinOpenを宣言し、次にwindow.openにSymWinOpenを代入することで、window.openがオブジェクトを作成して返すだけの関数にされます。したがってwindow.open関数を実行しても新しいウィンドウを開くことはできなくなります。

var SymRealWinOpen = window.open; // window.openと同じ動作をする関数

function SymWinOpen(url, name, attributes)
{
  return (new Object()); // 新しいオブジェクトを返す
}

window.open = SymWinOpen; // window.open関数を別のものに置き換える

 最後に次の部分ですが、window.open関数の内容をSymRealWinOpen関数と同じものにするという意味を持ちます。SymRealWinOpenは先に説明したように本来のwindow.open関数と同じ動作をしますから、再びwindow.openで新しいウィンドウを開けるようになります。

<SCRIPT language="JavaScript">
<!--

window.open = SymRealWinOpen; // window.openを本来の関数に戻す

//-->
</SCRIPT>

 なぜwindow.openを別のものにしたり元に戻したりと面倒なことをするのか。それはポップアップ広告が一般的にページ読み込みの際に実行されるからでしょう。

 window.openを無効にすれば取り合えずポップアップ広告は防げますが、新しいウィンドウを開くのは広告だけが目的ではないので完全にwindow.openが無効にされては不便なこともあります。したがって後からwindow.openで新ウィンドウを開けるようにしているのです。

 これは余談ですが、Norton Internet Securityの広告ブロックを突破する方法を説明します(笑)。

 といっても本当に簡単なこと、SymRealWinOpenがウィンドウを開く機能を持っているのだから、逆にそれを利用すればいいだけです。記述例としては以下のようになります。

<script type="text/javascript">
<!--
if (window.SymRealWinOpen) {
    var newWin = SymRealWinOpen("URL", "window名", "オプション"); // NISの広告ブロックが働いている場合
}
else {
    var newWin = window.open("URL", "window名", "オプション"); // NISの広告ブロックが働いていない場合
}
if (!newWin) {
        // ポップアップブロッカーが働いている場合の処理
}
//-->
</script>

 ちなみに一般的なポップアップブロッカーはページにソースに細工をすることはなく、またwindow.open()でnullを返すようになっているようです。したがって「if (!newWin) {〜}」の記述を入れることで、他のポップアップブロッカーでウィンドウが開かなかった場合の処理を書くこともできます。