XMLHttpRequest で User-Agent を誤魔化す方法
スマホ専用のページを取りたい
chrome-extension (chrome拡張) を作っている際、バックグラウンドでスマホ専用のページを取得する必要が出てきます。
スマホ専用のページは User-Agent を誤魔化せば取得できることが往々にしてあるので、今回はそれで解決を試みました。
User-Agent 偽装
chrome拡張でUser-Agentを偽装するには、chrome.webRequestを使うのが常套手段のようです。
# background.coffee # User-Agentの変更 chrome.webRequest.onBeforeSendHeaders.addListener( (details) -> headers = details.requestHeaders for i in [0..headers.length-1] if headers[i].name == 'User-Agent' headers[i].value = UserAgent break requestHeaders: headers {urls: ["対象URL" + '*']}, ["blocking", "requestHeaders"] ) # jQueryで同期取得 $.ajax( url: "対象URL", async: false, success: (data) -> console.log(data) )
また、chrome拡張のmanifestは次の通り。
(一部削除したので、動くかな?)
{ "manifest_version": 2, "name": "Ajax Tester", "version": "0.1", "description": "AjaxのUser-Agentを確認します", "background": { "persistent": true, "page": "html/background.html" }, "permissions": [ "webRequest", "webRequestBlocking", "対象URL" ] }
chrome.webRequestを使うために、"permissions"に3つほど設定してます。対象URLをここに書いて置かないと、取得権限が無いと弾かれてしまいます
偽装できない?
これを実行すると、対象URLのページに対するUser-Agentが変更されるようになります。
・・・しかし、なぜか background.js の中で XMLHttpRequest を使ってページを取得すると、偽装に失敗してしまいます。
同期 -> 非同期
chrome.webRequestのページを見ると、次の文言がありました。
http://developer.chrome.com/extensions/webRequest.html
Also synchronous XMLHttpRequests from your extension are hidden from blocking event handlers in order to prevent deadlocks.
・・・え、同期ダメなの?
ということで、次のように変更することで、偽装に成功しました。
# jQueryで非同期取得 $.ajax( url: "対象URL", async: true, #非同期! success: (data) -> console.log(data) )
非同期実行にすることで、background.jsの内部で発行するXMLHttpRequestでもヘッダーを書き換えることが出来るようです。
めでたしめでたし。