javascriptで、サブウィンドウで選択したデータをメインウィンドウに表示する(1)

サブウィンドウで選択したデータをメインウィンドウに表示する。クッキーだとデータサイズに制限があるので、グローバル変数を使う方法でやってみた。
グローバル変数を使うのは、あまりよくないが。

アプリの概要

メインウィンドウ、サブウィンドウの2つの画面があり、サブウィンドウで都道府県(都道府県コード、都道府県名)を選択して"add"ボタンを押すと、メインウィンドウに表示される。

サブウィンドウの"update_pref"を押すと、都道府県がランダムに変わり、さらに選択して"add"ボタンを押すと、重複を排除して、メインウィンドウに表示される。

主な仕様

<メインウィンドウ>

変数
 selected_pref:都道府県コード、都道府県名の組を保存する変数。初期値は空。
ボタン
 open_subwindow:サブウィンドウを開く。
関数
 update_table():変数selected_prefの内容を都道府県コードの昇順でソートし、テーブルの内容を置き換える。
オープン時の処理
 関数update_table()を実行する。


<サブウィンドウ>

変数
 prefcode:都道府県コード、都道府県名の組を定義する。
      wikipedia:全国地方公共団体コード都道府県コードを使用
ボタン
 add:選択した都道府県コード、都道府県名を変数selected_prefに追加し(重複は除く)、メインウィンドウの関数update_table()を実行する。
 update_pref:関数update_pref(5)を実行し、チェックボックス都道府県コード、都道府県名の組を5件含むテーブルを作成する。
関数
 update_pref(n):変数prefcodeから、都道府県コード、都道府県名をランダムでn組取り出し、チェックボックスを付加したテーブルを作成する。
オープン時の処理
 関数update_pref(5)を実行する。

作成したファイル

【main.html】

<meta charset="utf-8">
<body onload="update_table()">
<button onclick="open_subwindow()">open_subwindow</button>

<script>

var body = document.getElementsByTagName("body")[0];
var tbl  = document.createElement("table");
var selected_pref = {};

function update_table(){

  if( node = document.getElementById("prefcode") ){
    node.parentNode.removeChild(node);
  }

  keys = Object.keys(selected_pref);
  keys.sort(function(a,b){
    return a - b;
  });

  var tblbody = document.createElement("tbody");
  tblbody.id = "prefcode";

  //title
  var row = document.createElement("tr");

  var cell = document.createElement("td");
  var celltext = document.createTextNode("code");
  cell.appendChild(celltext);
  row.appendChild(cell);

  var cell = document.createElement("td");
  var celltext = document.createTextNode("prefecture");
  cell.appendChild(celltext);
  row.appendChild(cell);

  tblbody.appendChild(row);

  //data
  for(var i of keys){

    var row = document.createElement("tr");

    var cell = document.createElement("td");
    var celltext = document.createTextNode(i);
    cell.appendChild(celltext);
    row.appendChild(cell);

    var cell = document.createElement("td");
    var celltext = document.createTextNode(selected_pref[i]);
    cell.appendChild(celltext);
    row.appendChild(cell);

    tblbody.appendChild(row);

  }

  tbl.appendChild(tblbody);
  body.appendChild(tbl);

}

function open_subwindow(){

  window.open("sub.html","subwindow",
              "width=640,height=480,menubar=no,toolbar=no,status=no,scrollbars=no,location=no,resizable=no");

}
</script>


【sub.html】

<meta charset="utf-8">
<body onload="update_pref(5)">
<button onclick="add()">add</button>
<button onclick="update_pref(5)">update_pref</button>

<script>

prefcode = {
"01":"北海道",
"02":"青森県","03":"岩手県","04":"宮城県","05":"秋田県","06":"山形県","07":"福島県",
"08":"茨城県","09":"栃木県","10":"群馬県","11":"埼玉県","12":"千葉県","13":"東京都","14":"神奈川県",
"15":"新潟県","16":"富山県","17":"石川県","18":"福井県","19":"山梨県","20":"長野県",
"21":"岐阜県","22":"静岡県","23":"愛知県","24":"三重県",
"25":"滋賀県","26":"京都府","27":"大阪府","28":"兵庫県","29":"奈良県","30":"和歌山県",
"31":"鳥取県","32":"島根県","33":"岡山県","34":"広島県","35":"山口県",
"36":"徳島県","37":"香川県","38":"愛媛県","39":"高知県",
"40":"福岡県","41":"佐賀県","42":"長崎県","43":"熊本県","44":"大分県","45":"宮崎県","46":"鹿児島県","47":"沖縄県"
};

var body = document.getElementsByTagName("body")[0];
var tbl  = document.createElement("table");

function update_pref(n){

  var pref = {}; 

  if( node = document.getElementById("pref") ){
    node.parentNode.removeChild(node);
  }

  while( Object.keys(pref).length < 5){
    var code = (Math.floor(Math.random() * ( 48 - 1 ) + 1 )).toString().padStart(2,"0");
    pref[code]=prefcode[code];
  }

  keys = Object.keys(pref);
  keys.sort(function(a,b){
    return a - b;
  });

  var tblbody = document.createElement("tbody");
  tblbody.id = "pref";

  for(var i of keys){

    var row = document.createElement("tr");

    var cell = document.createElement("td");
    var check = document.createElement("input");
    check.setAttribute("type","checkbox");
    check.setAttribute("id",i);
    check.setAttribute("value",pref[i]);
    cell.appendChild(check);
    row.appendChild(cell);

    var cell=document.createElement("td");
    var celltext=document.createTextNode(i);
    cell.appendChild(celltext);
    row.appendChild(cell);

    var cell=document.createElement("td");
    var celltext=document.createTextNode(pref[i]);
    cell.appendChild(celltext);
    row.appendChild(cell);

    tblbody.appendChild(row);

  }

  tbl.appendChild(tblbody);
  body.appendChild(tbl);

}

function add(){

  var x = [].slice.call(document.getElementsByTagName("input"));
  for(var i in x){
    if(x[i].checked){
      console.log(x[i].id, x[i].value);
      if( !(window.opener.selected_pref[x[i].id]) ){
        window.opener.selected_pref[x[i].id]=x[i].value;
      }
    }
  }

  window.opener.update_table();

}

</script>


file:///.../main.html でアクセスした場合、サブウィンドウでaddボタンを押すと以下のエラーメッセージが表示された

Uncaught DOMException: Blocked a frame with origin "null" from accessing a cross-origin frame.

オリジンがnullになってしまう!?
webサーバ上で実行しないといけないみたい。