人間になりたい類人猿

人間以前の技術屋ブログ

iOS9のSafariにてiframe内でストアへリダイレクトさせると白画面で止まる問題

ある時、iframe内のリンクをクリックすると、一度サーバサイドのアプリケーションに遷移、リダイレクトでストアへ送るというプログラムを作った。
作った時(2015年春くらい)はiOSでも問題なく動いていた(はず)なのだが、今年の2月……

Aさん「何か白画面で止まったんだけど」
僕「は?!?!?!?!」

そんなわけで以下の現象が起こった……

「iOS9のsafariにてiframe内のリンクがリダイレクトをかます様な遷移方法だと、別タブが開いた後、白画面で遷移が止まる(ストアへリダイレクトしない)」

挙動を図にすると↓な感じ
f:id:wannabehuman:20160728131635j:plain

当時ググっても原因が分からなかったので、似たような動作をさせているリンク探してを追ってみたら、
どうやらiframeを使っている時にはtarget属性を_blankから_topに変えているようだ。
自分の方でも_topにしたら、正常にストアにリダイレクトされた(´ . .̫ . `)
※どうやらiOS9の仕様っぽい?(参考URL:
iTunes、App StoreへのリンクがSafariで開けないとき - あぷすた
)

なので、こんなhtmlとプログラムを組んでみて、挙動を調べてみた。
html(※リクエスト送られたくないので、localhostに変えてます)
 test.html(端末でアクセスするhtml)

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>iOS9</title>
</head>
<body>
	iframe外
	<h5><a href="http://localhost:8080/HttpRedirecter/Redirecter.aspx?rp=https://itunes.apple.com/jp/app/pazuru-doragonzu/id493470467?mt=8" target="_brank">リダイレクト有_URL_blank</a></h5>
	<h5><a href="http://localhost:8080/HttpRedirecter/Redirecter.aspx?rp=itms-apps://itunes.apple.com/jp/app/pazuru-doragonzu/id493470467?mt=8" target="_brank">リダイレクト有_URI_blank</a><h5>
	<h5><a href="http://localhost:8080/HttpRedirecter/Redirecter.aspx?rp=https://itunes.apple.com/jp/app/pazuru-doragonzu/id493470467?mt=8" target="_top">リダイレクト有_URL_top</a></h5>
	<h5><a href="http://localhost:8080/HttpRedirecter/Redirecter.aspx?rp=itms-apps://itunes.apple.com/jp/app/pazuru-doragonzu/id493470467?mt=8" target="_top">リダイレクト有_URI_top</a><h5>
	<h5><a href="https://itunes.apple.com/jp/app/pazuru-doragonzu/id493470467?mt=8" target="_brank">リダイレクト無_URL_blank</a></h5>
	<h5><a href="itms-apps://itunes.apple.com/jp/app/pazuru-doragonzu/id493470467?mt=8" target="_brank">リダイレクト無_URI_blank</a><h5>
	<h5><a href="https://itunes.apple.com/jp/app/pazuru-doragonzu/id493470467?mt=8" target="_top">リダイレクト無_URL_top</a></h5>
	<h5><a href="itms-apps://itunes.apple.com/jp/app/pazuru-doragonzu/id493470467?mt=8" target="_top">リダイレクト無_URI_top</a><h5>
	
	iframe内<br>
	<iframe src="redirect.html" >
	</iframe>
	
</body>
</html>


 redirect.html(iframe内のhtml)

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
	<h2>iOS</h2>
	<h5><a href="http://localhost:8080/HttpRedirecter/Redirecter.aspx?rp=https://itunes.apple.com/jp/app/pazuru-doragonzu/id493470467?mt=8" target="_brank">リダイレクト有_URL_blank</a></h5>
	<h5><a href="http://localhost:8080/HttpRedirecter/Redirecter.aspx?rp=itms-apps://itunes.apple.com/jp/app/pazuru-doragonzu/id493470467?mt=8" target="_brank">リダイレクト有_URI_blank</a><h5>
	<h5><a href="http://localhost:8080/HttpRedirecter/Redirecter.aspx?rp=https://itunes.apple.com/jp/app/pazuru-doragonzu/id493470467?mt=8" target="_top">リダイレクト有_URL_top</a></h5>
	<h5><a href="http://localhost:8080/HttpRedirecter/Redirecter.aspx?rp=itms-apps://itunes.apple.com/jp/app/pazuru-doragonzu/id493470467?mt=8" target="_top">リダイレクト有_URI_top</a><h5>
	<h5><a href="https://itunes.apple.com/jp/app/pazuru-doragonzu/id493470467?mt=8" target="_blank">リダイレクト無_URL_blank</a></h5>
	<h5><a href="itms-apps://itunes.apple.com/jp/app/pazuru-doragonzu/id493470467?mt=8" target="_blank">リダイレクト無_URI_blank</a></h5>
	<h5><a href="https://itunes.apple.com/jp/app/pazuru-doragonzu/id493470467?mt=8" target="_top">リダイレクト無_URL_top</a></h5>
	<h5><a href="itms-apps://itunes.apple.com/jp/app/pazuru-doragonzu/id493470467?mt=8" target="_top">リダイレクト無_URI_top</a></h5>
</body>
</html>

C#
Redirecter.aspx

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using log4net;

namespace HttpRedirecter
{
    public partial class Redirecter : System.Web.UI.Page
    {
        private static readonly ILog _logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        protected void Page_Load(object sender, EventArgs e)
        {
            //デコードとかはしない(生URLをパラメータに乗っける)
            string rp = Request.Params["rp"];

            //redirectじゃなくてもとりあえずリクエスト受けるだけにも対応(アプリ名が微妙になるが……まぁ……)
            if (rp != null) {
                Response.StatusCode = 302;
                _logger.Info("request has come: " +Request.Url + " redirect: " + rp);
                Response.Redirect(rp);
            } else {
                Response.StatusCode = 200;
                _logger.Info("request has come: "+ Request.Url);
            }
        }
    }
}


(カスタムuriスキームでストアアプリを立ち上げられるので、そっちでも試してみた)

項番 iframe内外 リダイレクト有無 target属性 URI 遷移の挙動
1 blank https する
2 blank カスタム する
3 top https する
4 top カスタム する
5 × blank https する
6 × blank カスタム する
7 × top https する
8 × top カスタム する
9 blank https しない
10 blank カスタム しない
11 top https する
12 top カスタム する
13 × blank https しない(別タブも開かない)
14 × blank カスタム しない(別タブも開かない)
15 × top https する
16 × top カスタム する

そもそもiframe内で_blankはヤバイみたい

以上