酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

User Agentを偽装してWebBrowserコントロールでiPhone用ページを閲覧する

本日の大西さんのブログに以下のような記事が書かれてありました。

「IE Mobileでモバイル優先とデスクトップ優先、2つのユーザーエージェントがありますが、Windows Phone 7.5/Windows Phone OS 7.1のWebBrowserコントロールのユーザーエージェント文字列はどうなりますか?」

という質問がありましたので、記事に残します。

回答としては、「Internet Explorer Mobileの設定に依らず、モバイル優先のユーザーエージェントになります」

Windows Phone : WebBrowserコントロールの User Agent文字列は何? - Akira Onishi's weblog - Site Home - MSDN Blogs

とのこと。WebBrowserコントロールはモバイル向けのUser Agentしか持たないらしいです。IE Mobileの方は切り替え可能なのにコントロールになると使えないなぁ……と思ったのですが、ななふぉの@tezawalyさんから「WebBrowser.Navigate(Uri, String, String)メソッドを使ったらUser Agentを偽装出来るのでは?」とアドバイスを頂きました。

てっとりばやくiPhoneのUser Agentを偽装してみましょう。iPhoneのUser Agentはこんな感じです。

Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_2 like Mac OS X; ja-jp) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7D11 Safari/528.16

たぶん厳密に判定してるサイトは少ないと思うので頭の「Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en)」だけを使わせてもらいます。WebBrowser.Navigateメソッドを呼ぶコードは以下の通りです。

using System;
using Microsoft.Phone.Controls;

namespace WebBrowserUATest {
    public partial class MainPage : PhoneApplicationPage {
        public MainPage() {
            InitializeComponent();
        }

        //string URL = "http://www.cman.jp/network/support/go_access.cgi";
        string URL = "http://www.yahoo.co.jp";

        // WP7デフォルトのUser Agentを使用
        private void button2_Click(object sender, System.Windows.RoutedEventArgs e) {
            webBrowser1.Navigate(new Uri(URL));
        }

        // 偽装したiPhoneのUser Agentを使用
        private void button1_Click(object sender, System.Windows.RoutedEventArgs e) {
            var ua = string.Format("User-Agent: {0}",
                "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en)");
            webBrowser1.Navigate(new Uri(URL), null, ua);
        }
    }
}

実行結果(ブラウザ情報の判定サイトの場合)

さて、上記のコードを実行した結果ですが、ブラウザ情報の判定サイトの判定はこんな感じです。

デフォルトのUser Agentの場合

Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; Microsoft; XDeviceEmulator)

という結果になりました。(大西さんのサイトとUser Agentが若干異なっているのは実機ベースの確認結果なのと、エミュレータでの確認結果の差です)

iPhoneのUser Agentの場合

Navigateメソッドの引数として指定したUser Agentが表示されていることが確認出来ました。

Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en)

実行結果(Yahoo! Japanの場合)

次にiPhoneの販売元でもあるソフトバンクのYahoo! Japanでの実行結果を見てみましょう。

デフォルトのUser Agentの場合

Yahoo!JapanはまさかのWindows Phone 7非対応!!。PCサイトへ飛ばされます。ソフトバンクからWindows Phoneがリリースされる見込みは無いのでしょうか……

iPhoneのUser Agentの場合

m.yahoo.co.jpへリダイレクトされて、きちんとiPhone用にカスタマイズされたサイトが表示されました。Android用のUser Agentを使ってもこっちへリダイレクトされると思うけど、Windows Phone 7だけが置いてけぼりになっている悲しい事実が明らかになりました。

追記

今回の記事ではXAMLはたぶん要らないと思うけど、一応掲載しておきます。

<phone:PhoneApplicationPage 
    x:Class="WebBrowserUATest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="SOFTBUILD" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="UA Test" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <phone:WebBrowser Name="webBrowser1" Margin="0,0,0,80" IsScriptEnabled="True" />
            <StackPanel Orientation="Horizontal" VerticalAlignment="Bottom">
            	<Button Content="UA Default" Height="72" x:Name="button2" VerticalAlignment="Top" Width="228" Click="button2_Click" />
            	<Button Content="UA iPhone" Height="72" x:Name="button1" VerticalAlignment="Top" Width="228" Click="button1_Click" />
            </StackPanel>
        </Grid>
    </Grid>
</phone:PhoneApplicationPage>