🦁
【JavaScript】iOSのSafariをUserAgentで判別する方法
どうもZenn初投稿のka_wa_ha_giです。
最近、WebRTCを使う機会があり、実装を進めておりました。
そこでiOSのブラウザでWebRTCに対応しているのはSafariのみという問題にぶつかりまして、その回避策としてUserAgentでの分岐という手段を用いました。
以前に比べ、かなり変更されていて苦戦したのでまとめてみました。
safariが文字列として含まれてる問題
iPhoneXでUserAgentを確認した結果が下記になります。
- Safari
Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1
- Chrome
Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/85.0.4183.109 Mobile/15E148 Safari/604.1
- Firefox
Mozilla/5.0 (iPhone; CPU OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/28.2 Mobile/15E148 Safari/605.1.15
- Edge
Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 EdgiOS/45.8.10 Mobile/15E148 Safari/605.1.15
確認した全てのブラウザにsafari
が含まれているのです。
では、どうやって判別するのか
パッケージを使用する
detect-browserというパッケージを使用するのが手っ取り早いです。
「なんだパッケージ使うのかよ」と思われる方もおられるかもしれません。
しかしUserAgentは仕様や各ブラウザ/OSのバージョンにより今後も変わっていく可能性があるため、判定する責務をパッケージに任せられるなら任せた方が良いと思いました。楽ですし
import { browserName, detectOS } from 'detect-browser';
/**
* @class Version
* @description デバイス情報を判定する処理
*/
export class Version {
private readonly ua = window.navigator.userAgent;
private readonly browserName = browserName(this.ua);
private readonly detectOS = detectOS(this.ua);
private readonly bodyElm = document.querySelector('body');
public isSP = false;
constructor() {
this.eventHandler();
}
private eventHandler(): void {
this.judgeSmartPhone();
this.handleAddClass();
}
/**
* スマートフォンかどうか判別
*/
private judgeSmartPhone(): void {
switch (this.detectOS) {
case 'Android OS':
case 'iOS':
case 'Windows Mobile':
case 'BlackBerry OS': {
this.isSP = true;
}
}
}
/**
* bodyにclass追加
*/
private handleAddClass(): void {
if (!this.bodyElm) {
return;
}
switch (this.browserName) {
case 'ie':
case 'edge':
case 'firefox': {
this.bodyElm.classList.add(this.browserName);
break;
}
case 'safari':
case 'ios': {
this.bodyElm.classList.add('safari');
break;
}
}
if (this.isSP) {
this.bodyElm.classList.add('isSP');
}
}
}
既存の正規表現部分を更新する
自分でif文を書いて分岐させている方も多いと思います。
そこでdetect-browserのtsファイルを読んでみてください。Safari以外も正規表現で判別しているため、かなり参考になるはずです。
iOSのSafariは下記で分岐できます。
/Version\/([0-9\._]+).*Mobile.*Safari.*/
ちなみにPCのSafariは下記で.*Mobile
部分をトルことで判別できます。
/Version\/([0-9\._]+).*Safari/
まとめ
正規表現は人類に早かった。
Discussion