window.postMessageを使ってiframeの中のリンクを外のwindowで遷移させる

まとめ

やりたいこと

iframe の中のリンクをクリックしたら元 window で遷移してほしい。

できた

前提としては 元 window の JavaScript も iframe 内の JavaScript も自由にいじれること。

  1. 元 window で iframe の load が終わったら iframe の window に対して postMessage で自分の origin を伝える
  2. iframe 内の window で click を拾って url を window.parent.postMessage で元 window に送る
  3. 元 window は送られた url を location にぶちこむ

できた!

分かったこと

  • そもそも iframe って許可されていないとコンテンツの表示もできなくなってた
    • X-Frame-Options とか最近はセキュリティ関係のヘッダいろいろあるんだね
    • Sinatra はデフォルトセキュア寄りなので何も表示されずに悩んだ
  • window オブジェクトとか普段触らないのでアクセス方法分からなくなる
  • postMessage って自由に送れるのかと思ったら送信先の origin をちゃんと送る側が分かってないとダメ
  • iframe の src まんまみたいなもんじゃんと思ったけど、逆方向の時には工夫が必要
  • window.postMessage では object は送れない。より複雑な双方向のやりとりをするには JSON.stringify などを使ってデータ構造を持たせないと厳しそう。

やったこと

ざっくり以下のような感じ。

parent window

<!-- iframe を作る -->
<iframe name="widget" src="http://example.jp"></iframe>

<script type="text/javascript">

/** iframeのコンテンツを読み込み終わったらparentの何か送る(なんでもよい) */
document.getElementsByName('widget')[0].addEventListener('load', function(e) {
  window.frames.widget.postMessage('loaded', 'http://example.jp');
});

/** iframe内のクリックされたurlが送られてくるのでlocationを書き換える */
window.addEventListener('message', function(e) {
  if ( e.data ) {
    location = e.data
  }
}, false);

</script>

iframe の中(http://example.jp)で jQuery を使ったとする。

/** parent windowのoriginを保存 */
window.addEventListener('message', function(e) {
  widget.target = e.origin;
});

/** リンクをクリックしたらparent windowに教える */
$('a').on('click', function(e) {
  window.parent.postMessage($(e.target).attr('href'), widget.target);
});

工夫したところ、悩んだところ

iframe 内の window では parent の origin が分からないのでそのままでは postMessage の際に origin を指定できない。そこで parent 側で iframe の内容の load イベントを待って parent の情報を送ってやる。

iframe の event を拾うには iframe 要素を、iframe 内に message を送るには window オブジェクトを、使い分ける必要があってなんかメンドイ。

参考

仮想マシンのディスクの構成で悩む

VMware での仮想化を決意したわけですが、実際にどういう構成で仮想マシンを作るかっつーのがまた悩むところなわけでして。というのも、migration 目的とは言えただの実験サーバとも違うので、あんまり遅くなってもらっちゃ困るのです。お手軽に同一ドライブで仮想ディスクなんてことをするとたぶんちょっとかなりつらいと思うので、ならば物理ディスクを仮想マシンのドライブとして割り当てたらどうか、というところまでは思いつきました。

cf. [ThinkIT] 第2回:ドメインUのI/Oパフォーマンスチェック (1/3)

しかし。

migration の前段階の実験環境は Celeron 850MHz + IDE 40GB という超しょぼい機械。これで物理ディスクをドライブとして割り当てると結構ややこしいことになってしまうのです。

  • 同一ドライブの別パーティションから起動しようと思うと、ブートローダは同じものが立ち上がってしまう
  • ということは VMware ホストもゲストも同じブートローダが起動する OS を選べと言ってくるので、起動の自動化が難しい(そもそも可能なの?)

というか、マニュアルに

仮想マシンの物理ディスクをホストOSと同じ物理ディスクにインストールすることは絶対に避けてください。

って書いてあるorz1 ということで、

  • とりあえず仮想マシンのブートセクタは仮想ディスク上に置くようにする
  • 起動時や通常 read, exec しかしないファイルはこっちに置く
  • 書き換えるデータだけ追加した物理ドライブに置く

という構成にしました。まぁ実験段階ですし2。migration 先はもう少しまともにディスクの追加とかできる環境なので、パフォーマンス的にもそこそこ生サーバに近づけるんじゃなかろうかと思っています。

  1. たぶん別パーティションでもだめ、って意味なんだと思う。一応仮想ディスクの方にゲスト OS をインストールし終わっていれば、同じドライブ上に物理ディスクを確保しても起動時に怒られたりはしない。もちろんこの状態で本番運用しようとは思わないけど。 

  2. とは言え今後も「実験」はどんな理由にせよあると思うのでこうしてメモを残しているわけですが。 

ハンセン病 vs らい病

らい病と呼ばれていた時代に事実として差別があったとしても言葉自身が差別的な意味を持つとは限らない(すべての専門用語まで置き換わっているわけではない)し、逆にハンセン病という言葉の時代であっても近年もアイスターの保有する熊本のホテルで差別があったわけだし、らい病と言ってしまった南野法務相に差別意識があったわけでなし1、叩きやすいからって叩いて喜ぶのはどうかと思うまる

まぁ事実として報道するのは別に構わないし、確かに脇が甘いというか、国務大臣としてなんだか頼りないなぁという気持ちも分からないではないが、今はもう少し見守ってやろうぜおい、という気持ちの方が強いかな。そりゃ答弁とかうまい方がいいけど、押しが強いだけの人なんかよりまだだいぶマシですよ。

  1. これは議論を待たないと思うんだけどなぁ 

知らんかった < xrea

xrea の広告免除サービスを使ってるんだけど、これディスク容量が増えるんだ。一気に 50MB → 1000MB. 前からそうだっけ? もっとバシバシ告知すればいいのに。

しかも Web インターフェイスのみだけど cron も使えるじゃーん。使っておきながら全然サービスを理解してなかったよー。

あと気づいてなかったサービス

  • APOP が使えねーと思ってたら POP over SSL だった
  • 当然 SMTP も IMAP も over SSL で ok. SMTP-Auth にも対応してるから Thunderbird で使うのに嬉しいぞ
  • spam フィルタ、ウィルスフィルタってのがあるんだけど、これは基本のメールアドレスでも使えるのかな? つーか設定はどこからやるんだろう。
  • SSL の証明書が localhost 発行なのはあれか、ちゃんとした証明書発行したかったらお金払ってねってことかな? まーそらそうだわな。
  • Web メールも SSL 対応してました。(証明書関係で警告出まくりだけど。)

うーん、こんだけの容量があって IMAP 使えるならけっこういろんな使い方できそうだなぁ。金払って半年もこんな基本的なことが分かっていなかったなんてorz

Type Ahead Find の罠

Wiki を常用している関係で AccessKey にやたらめったらお世話になっている。ところが、Mozilla で作業中に、なんかの拍子に AccessKey がまったく効かなくなってしまうことがある。

なんでだ、なんでだ、と思っていたら Type Ahead Find の仕業でした。Type Ahead Find とは最近入った(どのバージョンか忘れたなり)「何かキーを押すとそのキーに対応した文字列を含むリンクテキストを検索してくれる」というシロモノで、たぶんきっと使いこなすとかなり便利なんでしょう。

でも Type Ahead Find のモードに入ったっきり他の操作をぶんどってしまうし、リンクテキストがあっちゃこっちゃにあった場合、ウィンドウの内容がガタガタスクロールしてかなり気持ち悪いです。

しかも、えー。オフにする方法が分かりません。

インスピレーション7 英語トライアル版@Win2k

使ってみた。

  • まずフォントが日本語じゃないので日本語出ません。
  • 日本語のフォントを選べばよいのですが、フォント追加のダイアログで日本語のフォント名は表示できません。
  • とりあえずあてずっぽで選択してとにかくメニューに追加します。
  • そうすれば何のフォントだか分かります。
  • まだ問題があって、インライン入力できません。
  • あと、バックスペースを押しても1バイトずつ文字が消えるのでかったるいです。

そんな感じ。6 は Mac だと Classic でしか使えないのに日本語対応は 6 までなのです。

About

例によって個人のなんちゃらです

Recent Posts

Categories

Tool 日々 Web Biz Net Apple MS ことば News Unix howto Food PHP Movie Edu Community Book Security Text TV Perl Ruby Music Pdoc 生き方 RDoc ViewCVS CVS Rsync Disk Mail FreeBSD Cygwin PDF Photo Zebedee Debian OSX Comic Cron Sysadmin Font Analog iCal Sunbird DNS Linux Wiki Emacs Thunderbird Sitecopy Terminal Drawing tDiary AppleScript Life Money Omni PukiWiki Xen XREA Zsh Screen CASL Firefox Fink zsh haXe Ecmascript PATH_INFO SQLite PEAR Lighttpd FastCGI Subversion au prototype.js jsUnit Apache Trac Template Java Rhino Mochikit Feed Bloglines CSS del.icio.us SBS qwikWeb gettext Ajax JSDoc Rails HTML CHM EPWING NDTP EB IE CLI ck ThinkPad Toy WSH RFC readline rlwrap ImageMagick epeg Frenzy sysprep Ubuntu MeCab DTP ERD DBMS eclipse Eclipse Awk RD Diigo XAMPP RubyGems PHPDoc iCab DOM YAML Camino Geekmonkey w3m Scheme Gauche Lisp JSAN Google VMware DSL SLAX Safari Markdown Textile IRC Jabber Fastladder MacPorts LLSpirit CPAN Mozilla Twitter OpenFL Rswatch ITS NTP GUI Pragger Yapra XML Mobile Git Study JSON VirtualBox Samba Pear Growl Mercurial Rack Capistrano Rake Win RSS Mechanize Sitemaps Android JavaScript Python RTM OOo iPod Yahoo Unicode Github iTunes God SBM friendfeed Friendfeed HokuUn Sinatra TDD Test Project Evernote iPad Geohash Location Map Search Simplenote Image WebKit RSpec Phone CSV WiMAX USB Chrome RubyKaigi RubyKaigi2011 Space CoffeeScript Nokogiri Hpricot Rubygems jQuery Node GTD CI UX Design VCS Kanazawa.rb Kindle Amazon Agile Vagrant Chef Windows Composer Dotenv PaaS Itamae SaaS Docker Swagger Grape WebAPI Microservices OmniAuth HTTP 分析基盤 CDN Terraform IaaS HCL Webpack Vue.js BigQuery Middleman CMS AWS PNG Laravel Selenium OAuth OpenAPI GitHub UML GCP TypeScript SQL Hanami Document SVG AsciiDoc Pandoc DocBook Develop Jekyll macOS Node.js Vite Heroku Transformer AI Data Cloud Wasm