読者です 読者をやめる 読者になる 読者になる

IE6ではJavaScriptで動的に作成したiframeに対してsubmitできない(IE7は未確認) ->解決

スポンサーリンク

IE6だと下記のようなHTMLを表示すると、別ウインドウに対してsubmitされてしまいます。
なお、Firefox2.0、Opera9.2だとOKです。(iframeに対してsubmitされる)

<html>
  <head></head>
  <body>
    <form enctype="multipart/form-data" method="post">
      <input type="file" name="userfile" id="file"></input>
    </form>
    <script>
      var iframe = document.createElement('iframe');
      iframe.name = 'targetFrame';
      document.body.appendChild(iframe);

      var form = document.forms[0];
      form.action = 'javascript:alert(1)'; // 適当
      form.target = iframe.name;
      form.submit();
    </script>
  </body>
</html>


下記のようにiframeを最初からマークアップしてあれば、ちゃんとiframeに対してsubmitされます。

<html>
  <head></head>
  <body>
    <form enctype="multipart/form-data" method="post">
      <input type="file" name="userfile" id="file"></input>
    </form>
    <iframe name="targetFrame" id="targetFrame"></iframe>
    <script>
      //var iframe = document.createElement('iframe');
      //iframe.name = 'targetFrame';
      //document.body.appendChild(iframe);

      var iframe = document.getElementById('targetFrame');

      var form = document.forms[0];
      form.action = 'javascript:alert(1)'; // 適当
      form.target = iframe.name;
      form.submit();
    </script>
  </body>
</html>


iframeがまだ描画されていないのかなと思い、onreadystatechangeイベントでiframeの読み込み
完了をまってからsubmitしても結果は同じ。。

<html>
  <head></head>
  <body>
    <form enctype="multipart/form-data" method="post">
      <input type="file" name="userfile" id="file"></input>
    </form>
    <script>
      var iframe = document.createElement('iframe');
      iframe.name = 'targetFrame';
      document.body.appendChild(iframe);

      // IE用
      iframe.onreadystatechange = function() {
        if (this.readyState == 'complete') {
          var form = document.forms[0];
          form.action = 'javascript:alert(1)'; // 適当
          form.target = iframe.name;
          form.submit();
        }
      }
    </script>
  </body>
</html>


追記@2007/08/31
iframe.contentWindow.name に iframe.nameで指定したのと同じ文字列を設定すればIEでも動きました。
Firefoxだと、bodyにappend前にiframe.nameに設定していた文字列が、appendされた際にiframe.contentWindow.nameにも反映されるようです。なお、appendされた後にiframe.nameを変更しても、iframe.contentWindow.nameには反映されませんでした。
iframe.nameに何も設定してなくても、iframe.contentWindow.nameに設定されていればちゃんと動くのですが、HTMLとして書いた場合とプロパティが違ってくるのがいやなので、両方に設定するようにしました。

<html>
  <head></head>
  <body>
    <form enctype="multipart/form-data" method="post">
      <input type="file" name="userfile" id="file"></input>
    </form>
    <script>
      var iframe = document.createElement('iframe');
      iframe.name = 'targetFrame';
      document.body.appendChild(iframe);
      iframe.contentWindow.name = iframe.name; // 追加

      var form = document.forms[0];
      form.action = 'about:blank'; // 適当
      form.target = iframe.name;
      form.submit();
    </script>
  </body>
</html>

dara-jさんからコメントで教えていただきました。ありがとうございます!