スポンサーリンク

WSHやJavaScriptで「実行時エラー:解放されたスクリプトからコードを実行できません」の意味と対処法


JavaScript,もしくはWSH/JScriptで,プログラムの実行中に下記のエラーメッセージに遭遇することがある。

「実行時エラー:解放されたスクリプトからコードを実行できません」

この意味と対処法について。

JavaScriptで,「なくなったオブジェクトを参照してメソッド呼び出し」すると発生する

JavaでいうところのNullPointerExceptionに似ている。

すでに破棄済みの,つまりメモリから解放されたオブジェクトを使おうとすると起きるエラーだ。


特に,解放済みのオブジェクトの「メソッドを呼び出し」すると,このエラーになる。


hogeという関数はメモリから削除済みであるにもかかわらず,

hoge() という関数呼び出しをしてしまうと,

その行の時点で「解放された関数」を呼び出していることになり,NGというわけだ。


「解放されたスクリプト」って何よ?と思うだろうが,

要するに,「メモリから消えてしまっている関数」のこと。


その関数を実行できないので

「解放されたスクリプト(の関数)」から「コードを実行(メソッド呼び出し)できません」

というメッセージ内容になる。

このエラーを引き起こすコードのよくある例

よくあるのは,JavaScriptでWindowオブジェクトをあつかっている最中に

もう閉じて,メモリ上から消えてしまったウィンドウなのに,

そのウィンドウの持つメソッドを呼び出してしまった。

なんて時に発生する。


ウィンドウのかわりに,ifraneでもよい。

ブラウザ上で既に消えてしまったものを参照しているのがよくない。

消えてしまったオブジェクトのメソッドを呼び出しているわけだ。


マイクロソフトの公式ページにも,iframeでのエラー発生例が書いてある。

IE8以下では発生しないエラーだが,それは本来ならエラーとなるべき「ヌルポ」だった。

IE9以降で修正され,ちゃんとエラーを返すようになった,というわけ。

DOM から削除したときに iFrame リソースが解放される (Windows)
https://msdn.microsoft.com/ja-jp/library/gg622929(v=vs.85).aspx
 
iframe 要素を Web ページの DOM から削除したときは、
この要素に関連付けられたリソース (およびその子) を解放する必要があります。
たとえば、メモリを再利用したり、ウィンドウ ハンドルを閉じたりする必要があります。
 
IE9 以降では、iframe 要素が DOM から削除され、
実行中のコードが完了するとすぐに、
この要素に関連付けられたリソースが解放されます。
 
iframe またはその子に対して DOM 関連の API を呼び出すと例外が発生し、
"解放されたスクリプトからコードを実行できません" というメッセージが表示されます。


このエラーを経験する人の経験談も,Windowやiframeを操作しているケースばかり。

消えたDOMオブジェクトのメソッド呼び出しでコードが止まっている。

開放されたスクリプトからコードを実行できません - MyMemoWiki
http://typea.info/tips/wiki.cgi?page=%B3%AB%CA%FC%A4%B5%A4%EC%A4%BF%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8%A4%AB%A4%E9%A5%B3%A1%BC%A5%C9%A4%F2%BC%C2%B9%D4%A4%C7%A4%AD%A4%DE%A4%BB%A4%F3

  • ダイアログを閉じた時点で、実装されたメソッドの内容は開放されてしまうんだろう。


IE9でiframe内で遷移した場合window.parentのメソッドを呼べない | Into my web
http://kozo002.blogspot.jp/2012/07/ie9iframewindowparent.html

  • 「信頼性の低いスクリプトから親ウィンドウにあるオブジェクトのメソッドを実行できない」ってことですかね!!
    • pushじゃなくて代入にした。 window.parent.videos[window.parent.videos.length] = video;
    • そうしたら問題なく動いた。(メソッド呼び出しではなく)プロパティの参照と代入は問題ないみたい。

WSHの場合

自分がこのエラーメッセージに遭遇したのは,WSH/JScriptでIEを自動操作しているときだった。

エラーを起こした部分の擬似コードは下記の通り。

// jQueryでWebスクレイピングした要素の配列を,elementsに格納してある。

for( var i = 0; i < elements.size(); i ++ ){

  if( 条件 ){

    処理;

    画面遷移:
  }

}

何がまずいか,おわかりになるだろうか。


for文のループ制御部分で,jQueryのsize()を呼び出している。

だが,途中で画面遷移してしまうと,このelementsという変数の中身がメモリから消えてしまうので

それに対するメソッド呼び出しの size() はエラーになるのだ。


解放済みのスクリプトから,メソッド(コード)を呼び出そうとしている。

それで,冒頭のエラーメッセージにたどり着いた。


結論として,解放処理はきちんと実装しましょう。

動的なクエリ文字列を含む「GETパラメータ付きURL」はSEOに悪影響せず,静的に変更する必要なし。「理解しやすいURL」をこころがけよう

「GETリクエストのパラメータ」を含むURLは,SEO的に不利なのだろうか?

.htaccessなどの設定を変えて,スラッシュ区切りの「静的URL」に書き換えるべきだろうか?

下記で解説。

静的URLへ,無理して書き換えるべきではない

パラメータ文字列を,無理に改変して「静的URL」に書き換えると,マイナスになる。

動的URLから静的URLへの変更は,無理して行うべきではない。


なぜかというと,動的URLのままなら「/?パラメータ名=値」となっており
Googleから見ても意味がわかりやすい。

ところが,静的URLに書き換えて「/値/」だけのURLにしてしまうと,
「何のパラメータがその値なのか?」という意味を
URLからくみ取ることができない。

Googleにとって,理解しづらいURLになってしまうのだ。


だからこの場合は,動的URLのままのほうが,Googleから見て高評価を保ちやすい。

グーグル、動的URLはそのまま、静的URLへ書き換えすべきでない | 海外SEO情報ブログ
https://www.suzukikenichi.com/blog/google-prefers-dynamic-url-rather-than-static-url/

  • 今回Googleは、動的URLはそのままにしておくべきで、静的URLに変換することはかえってマイナスになると、指針を180度転換しました。
    • 技術の進歩により、動的URLの処理性能が向上し、パラメータが何を意味するのかも理解できるようになったそうです。

動的URLのままでよいが,「パラメータの名称をわかりやすく」するべし

大事なことは,
「URLが含むパラメーターの意味をGoogleが理解しやすい」
ということ。

ほかのWebアプリでもよく使われているパラメーター名,

または,シンプルな英単語のパラメーター名を使おう。

不必要に静的化したURLよりもパラメータ付きURLをGoogleは好む | 海外SEO情報ブログ
https://www.suzukikenichi.com/blog/google-prefers-the-clean-parameterized-url-to-unnecessary-url-rewriting/

  • パラメータの文字列から内容を想起できて, かつ幅広く使われているパラメーター名であるなら、Googleにとってはパラメータの意味を理解しやすくなります。


パラメータの名称の決め方として,

「ページ内の内容と関係があるようなパラメータ名」がよい。

そうすれば,URLを見ただけで,ページの内容を推測しやすくなり
ユーザフレンドリーなURLだと言えるから。

Google 検索エンジン最適化(SEO)スターターガイドについて(サイト構造の改善 URLの構造を改善しよう) | インバウンドマーケティング/Facebookアプリ/Web制作 Hivelocity ハイベロシティ
http://www.hivelocity.co.jp/blog/3261

  • URLが「ページの内容と関連する単語」を含んでいれば、IDや不可解なパラメータで構成されたURLに比べて、ユーザーと検索エンジンの両方にページについての情報をより多く伝えられます。
    • URL内にわかりやすい単語を使用することで、リンクをたどる前にリンク先のページの内容が、より伝わりやすくなります。

パラメーターの数が多い場合は,静的URLに書き換えるか,Webマスターツールで設定しよう

動的URLから静的URLへの書き換えを行ったほうがよいケースは,

パラメータの数が3つ以上で,URLが読みにくい場合だ。


こういうケースでは,静的URLへの書き換えによってSEO上もプラスの効果がある。

「ユーザーフレンドリーなURL」になるよう配慮しよう。

URLの静的化は行ったほうがよいのか? URLの実績検証 | もうSEOなんて大嫌いだ!
http://yutasuzuki.com/directory/url-static/

  • さすがに パラーメーターの文字数が長かったり、「?」や「&」などの演算子が3つ以上あったりすると Googleもインデックスしづらい
    • 静的化をしてから大幅にインデックス数が促進されました。


パラメータ付URL SEO対策 info.
http://www.infodot.jp/seo/parameter.html

  • Googleは、2006年10月まで、 "&id=" から始まるパラメータのURLをインデックスしなかった。
    • これはGoogleのウェブマスターガイドラインにも記載されていた。
    • しかし、2006年10月に Googleの「ウェブマスターのためのガイドライン」が更新され, インデックスされるようになった。
  • 多数のパラメータが付いたURLは問題がある可能性がある。
    • パラメータの数は1~2が望ましい。
    • ユーザーフレンドリーなURLにリライトすることが望ましい。


どうしても動的URLのままで,パラメーターの数が多くなる場合は,

Google Webマスターツールで設定しておこう。

動的URLと静的URLは、どちらのほうがSEO上有利になりますか? | SEO対策Q&A [SEO HACKS]
http://www.seohacks.net/basic/qa/dynamic-static-address_disadvantage/

  • 現在の検索エンジンにおいては、動的URLでも静的URLでも、SEO上の優劣の違いはありません。
    • 以前は、静的URLのほうが有利であると言われていた。
    • 最近では検索エンジンの処理能力も改善し、動的URLでも静的URLと大差なく処理できるようになっている。
  • パラメータが複雑になる場合には, ウェブマスターツールでURLパラメータの設定を行っておく

動的URLは,「コンテンツの重複が発生しやすい」のが問題点。重複を避ければ問題なし

注意点は,「重複コンテンツの発生を避ける」ということだ。


パラメータを含む動的ページの場合,
URLしだいで自由にページ内容を変えられる。

なので,URLが似ていれば,ページ内容も似たものになってしまう。

そうすると「重複ページ」(ミラーページ)が発生してしまい,SEO的にはペナルティを受ける。


明らかにわかることだが,これはURLの問題ではない。

Webアプリの設計の問題だ。

URLが静的であろうが,動的であろうが,重複コンテンツの対策は必要だから。


しかし,パラメータ付きのURLであれば,重複は発生しやすくなる。

重複コンテンツによって生じる問題とその対策 | SEO基礎知識 [SEO HACKS]
http://www.seohacks.net/basic/knowledge/duplicate-content/

  • 重複コンテンツが生成される状況として、下記のような場合が挙げられます。
    • URLの表記に一貫性が保たれてない場合
    • URLにパラメータが付与され、動的にURLが複数生成される場合


SEOの“新”ベストプラクティス(中編) - URL正規化/alt属性/meta keywords/フッターリンク など | Moz - SEOとインバウンドマーケティングの実践情報 | Web担当者Forum
http://web-tan.forum.impressrd.jp/e/2009/07/22/6106

  • パラメータを含むURLの使用はお勧めしない。
    • (既存のCMS設定などが原因で)どうしても必要な場合、パラメータの数は2つ以内にすることを推奨する。
  • パラメータ付きURLは,往々にして重複コンテンツの問題につながる。
    • これは相関データからも裏付けられていて、静的URLを持つページの方が, 高い順位を取る傾向が強い。


【事例】URLの擬似静的化はハマればものすごいSEO効果を生み出す | Next Generation SEO
http://seo.septeni.net/seo/1544.html

  • 複雑な動的URLは「インデックスされづらい」「ミラーページが発生しやすい」という2点の理由から、SEO上推奨出来ない。

パラメータの有無で,評価やキャッシュが分散してしまう現象に備えをしよう

「パラメータ付きの動的URL」の注意点として,

パラメータの有無によって評価が分散してしまいかねない,

という点がある。


まずPageRankについてだが,

パラメータの有無でページランクが分散せぬよう,

Google側では正規化してインデックスされる。

ページ側でも,canonicalなURLを提示するのを忘れないようにしよう。

URLのパラメータ有り無しで評価が分散しない為のSEO解決策
https://www.allegro-inc.com/seo/url-parameter

  • oogleのクロールチームは、パラメータ付きとなしのページで評価が分散しないよう、インデックスの正規化処理をしている。
    • 一般的なURLパラメータタグ、トラッキングタグを使用していれば、大抵は検知する事ができる。


また,普通にページを作ると,

パラメータなしのURLの内容が,Google内に保管される。

ページ内容のキャッシュも,パラメータなしのURLである。


なので,パラメータなしのURLの内容も,しっかりと作りこんでおくようにしよう。

[SEO]パラメータ付URLをキャッシュさせたい場合を考える | FEEL FINE
http://www.mizukkou.com/?p=279

  • かつての上司より以下のような相談を受けました。
    • Yahoo!では、パラメータ付きURLでキャッシュされてて、 Googleでは、パラメータ無しのURLでキャッシュされている。 パラメータ付きURLに統一できないもんかね!?

WebページのURLの長さは,ブラウザのGETリクエスト制約で,最大2000文字ほどに制限したほうがよい

URLの長さは,最大でも2000文字ほどの長さに収める必要がある。

これは,「GETリクエストの最大長」の制約となる。

  • (通信プロトコル面) HTTPの仕様上は,URLの長さに制限は無い。
  • (クライアント,ブラウザの面) IEは,URLの長さに制限がある。


つまりIEのせいなのだが…,

これはWebの世界では,事実上の標準的なリミットということだ。


そのため,GETのパラメータ文字列も,無限に長くはできない。

クエリ文字列を含めて,全体で2000文字ほどに収める必要がある。

Webアプリの設計時には注意しよう。

参考資料

HTTPの仕様では,もともとURLの長さに制限は無い。

[tech]HTTP GETメソッドのURIの長さ制限を調べてみた - Kazumi007の日記
http://d.hatena.ne.jp/Kazumi007/20090921/1253501500

  • HTTP1.1の仕様上は,HTTP GETで転送できるデータ量(=URIの長さ)には上限がない
    • HTTP GETメソッドにはRFC上、URIに255byteの制限はない
    • Webサーバ側でも,デフォルトでは制限されていますが、設定で変更することが可能。
  • いくらサーバ側で長いURLを受け付けられたとしても、ブラウザからリクエストを送信できなければ意味がありません。
    • IEは, MicrosoftがURLの上限に関する情報を公開している。 IE3.0~IE8.0までが対象となっているので、ほぼすべてのバージョンで2083文字以上の指定ができないと考えた方が良い
    • 制限が小さいせいで、IEがデファクトスタンダードになっている。


URLは最高何文字まで可能なのでしょうか? - HTML 解決済 | 教えて!goo
http://oshiete.goo.ne.jp/qa/7969461.html

  • HTTP 1.1 (RFC2616) では,URIの文字長に制限はありません
    • また,例えば data: スキーム(RFC 2397)ではURLは非常に長くなる。リソース自体を文字列化して URL にしてしまうため,リソースが大きくなれば文字列も膨大なものになる。
  • 送信フォームなどでURLの長さを200文字くらいに制限しているところもある
    • その目的は,データベース側が保存できる容量によるものだったり、サイト攻撃のスクリプトなどを埋めこまれないようにするための処置だったりする。


IEだけが特殊なブラウザであり,約2000文字を超えるURLを処理できない。

ChroneやFirefoxなどのモダンブラウザでは,32000文字ぐらいまで処理できるのに。

IE11で使用可能なURL文字数が2083文字しかない件 - 文系プログラマによるTIPSブログ
http://www.bunkei-programmer.net/entry/2014/09/03/213528

  • chrome等も厳密には制限はありますが,実質制限が無いのと同じ状況。
    • 実際はchromeの文字数制限より先に、webサーバ側のパケットサイズ制限にひっかかる
  • web開発者にとっては, URLの使用文字数というのは非常に重要
    • IEが対応してないからURL設計を特殊にしたり、IEだけjs/cssがおかしいから条件分岐したりするなど、IEだけおかしいという仕様のために,我々開発者は長年苦しめられている。


IE11 の URL の最大長はあいかわらず 2083 でした。他のブラウザは三万超えているのに・・・ : logical error
http://logicalerror.seesaa.net/article/383427331.html

  • IE11: 2083
  • Google Chrome: 32464
  • Firefox: 32491


Webサイトを開発する際に,

「IEだけは,なぜかAjaxが正常に動かない」などのトラブルに苦しめられ,

その原因がURLの長さだったりする。

[IE] URL に使用可能な文字数は最大 2,083 文字 | [ま]技術雑記
http://blog.kaburk.com/browser/ie-url-max-2083.html

  • サーバに非同期通信してた気がしたのでソースを調べてみると、prototype.jsにてAjax.Requestしていた。
    • しかし、そこのメソッドがGETになっていた。
  • IEで動かないという時にまず思い浮かんだのが、「URL長すぎ」


もし,URLの文字数を気にせず,たくさんのパラメータを送りたい場合は,

GETではなくPOSTでフォームを設置するようにしよう。

【PHP】GETとPOSTの違い、使い分けと使い方を紹介
http://scene-live.com/page.php?page=27

  • GETメソッドはデータをURLの末尾につけて送るので、制限されることになります。
    • 大量のデータを送信したい場合はPOSTメソッドを用いる
    • POSTメソッドは、URLの長さの制約から影響を受けない。


なお,この「URLを2000文字以下に制限」という制約は,

Webアプリとブラウザだけの問題ではない。

検索エンジンやSEOの観点から見ても,2000文字以下が推奨されているのだ。

「URLの長さは2,000文字より短くした方がいい」とGoogleのMueller氏がアドバイス | SEOモード
http://www.seomode.jp/seo/2014/03/08/2725/

  • サイトマップXMLで処理できるURLの長さも「2,048文字以下」と指定されています。