Webseiten für Smartphones ausliefern durch Auswertung des User-Agents

Mit dem Handy im Internet surfen gehört für viele Smartphone-Besitzer zum Alltag. Wegen der geringeren Bilschirmauflösung bieten viele Webseiten eine optimierte schmalere Version für mobile Geräte an. Oft sind diese Seiten dann unter ‚m‘ statt ‚www‘ erreichbar und sie werden auch in einem normalen Desktop-Browser angezeigt: m.wikipedia.org , m.zalando.de oder m.tagesschau.de

Falls eine Webseite auch für Smartphones optimiert ist, muss der Server nach einer Anfrage der ‚www‘-Webseite erst einmal ermitteln, ob der anfragende Browser auf einem Desktop-Rechner oder einem Smartphone ausgeführt wird. Falls es sich um ein Smartphone handelt, wird auf die ‚m‘-Webseite mit einem Redirect (z.B. HTTP-Code 302: Moved Temporarily) weitergeleitet.

Woher weiß der Server nun, welche Version der Webseite ausgeliefert werden muss. Der Browser übermittelt bei einer Anfrage einige Header-Informationen, wie zum Beispiel das Feld ‚User-Agent‚, das Auskunft über den verwendeten Browser gibt. Damit kann der Server bewerten, mit was für ein Gerät der Anwender surft (siehe auch Wikipedia-Artikel: Mobile Device Detection).

Internet Explore 6 auf Windows XP:
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)

Firefox 13 auf Mac OS X:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:13.0) Gecko/20100101 Firefox/13.0.1

IPhone 4.3:
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3 like Mac OS X; de-de) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8F190

Samsung Galaxy II:
Mozilla/5.0 (Linux; U; Android 4.0.3; de-de; Galaxy S II Build/GRJ22) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30

Welche ‚User-Agent‘-Kennung der eigene Browser verwendet, zeigt die Seite http://www.useragentstring.com/ an. Dort gibt es auch eine umfangreiche Liste verwendeter ‚User-Agent‘-Kennungen. Mit dem tollen Firefox-Plugin ‚User Agent Switcher‚ läßt sich diese Kennung ändern. Wem die angebotenen User-Agents nicht ausreichen, kann hier noch eine Vielfalt von User-Agents herunterladen und innerhalb des Plugins importieren. Also jetzt gleich mal ein iPhone auswählen und eine www-Webseite anfordern – es wird dann hoffentlich die mobile Variante angezeigt.

Wenn wir jetzt selbst solch eine Desktop/Mobile-Weiche serverseitig benötigen, haben wir (wie so oft) drei Möglichkeiten:

  • einen Service verwenden, wie WURFL
  • eine Bibliothek einsetzen, wie Categorizr (PHP) oder categorizr.js (JavaScript – Logik)
  • Weiche selber implementieren und bei Beschwerden nachbessern 😉 z.B. in Java:
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletResponse;
    
    public class MobileDetectionFilter implements Filter {
    
    	private static final String MOBILE_URL = "http://m.mydomain.de";
    
    	public void init(FilterConfig config) throws ServletException {
    	}
    
    	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    		String userAgent = ((HttpServletRequest) request).getHeader("User-Agent");
    		if (userAgent.contains("iPhone") || userAgent.contains("Android") || userAgent.contains("Mobile")) {
    			HttpServletResponse httpServletResponse = (HttpServletResponse) response;
    			httpServletResponse.sendRedirect(MOBILE_URL);
    		} else {
    			chain.doFilter(request, response);
    		}
    	}
    
    	public void destroy() {
    	}
    }
    

Wenn man mit Java unterwegs ist und den Jetty-Server einsetzt, könnte der Code für solch eine Mobile-Weiche wie das untenstehende Beispiel aussehen. In dem Beispiel wird der Benutzer nach Aufruf der Adresse http://localhost:8080 auf http://localhost:8080/mobile weitergeleitet, wenn ein Smartphone-Browser oder ein Browser mit entsprechender ‚User-Agent‘-Kennung verwendet wird.

package de.bruns.example.playground.useragent;

import java.io.IOException;
import java.util.EnumSet;

import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;

public class MobileDetectionJetty {

	public MobileDetectionJetty() throws Exception {

		final ServletContextHandler context = new ServletContextHandler();

		Server server = new Server(8080);
		context.setServer(server);

		context.addServlet(MyDesktopServlet.class, "/");
		context.addServlet(MyMobileServlet.class, "/mobile");

		context.addFilter(MobileDetectionFilter.class, "/", EnumSet.of(DispatcherType.REQUEST));

		server.setHandler(context);

		server.start();
		server.join();
	}

	public static class MyDesktopServlet extends HttpServlet {
		@Override
		protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
			resp.getWriter().println("Desktop version !");
		}
	}

	public static class MyMobileServlet extends HttpServlet {
		@Override
		protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
			resp.getWriter().println("Mobile version !");
		}
	}

	public static class MobileDetectionFilter implements Filter {
		private static final String MOBILE_URL = "/mobile";

		public void init(FilterConfig config) throws ServletException {
		}

		public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
			String userAgent = ((HttpServletRequest) request).getHeader("User-Agent");
			if (userAgent.contains("iPhone") || userAgent.contains("Android") || userAgent.contains("Mobile")) {
				HttpServletResponse httpServletResponse = (HttpServletResponse) response;
				httpServletResponse.sendRedirect(MOBILE_URL);
			} else {
				chain.doFilter(request, response);
			}
		}

		public void destroy() {
		}
	}

	public static void main(final String[] args) throws Exception {
		new MobileDetectionJetty();
	}
}

Übrigens – falls eine Webseite mal merkwürdig beim Surfen aussieht, einfach den ‚User Agent Switcher‘ wieder auf ‚default‘ zurückschalten 🙂

Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s