JavaScriptだけでUser-Agentを偽装してWebページを取得する
初めに、IE9以上でしか動きません。
しかもバグ持ちで、ページによっては画面が真っ白になることがあります。
同じスクリプトを2回実行すると直る可能性あり。
ちなみに Google News でテストしました。
ということで、スクリプトです。
(function(){ if (document.createRange) { // Rangeオブジェクト多用してるのでこれが使えないとお話にならない var range = document.createRange(); range.selectNodeContents(document.documentElement); var xhr = new window.ActiveXObject("MSXML2.XMLHTTP"); // XHRオブジェクト生成 xhr.open("GET", location.href, true); // ここでUser-Agentを指定します。 xhr.setRequestHeader("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9A405 Safari/7534.48.3"); // ここでキャッシュを無効にして 304 が返らないようにします。 xhr.setRequestHeader("Pragma", "no-cache"); xhr.setRequestHeader("Cache-Control", "no-cache"); xhr.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT"); // 非同期通信なので必須 xhr.onreadystatechange = function(){ if (xhr.readyState===4 && xhr.status===200) { var root = document.documentElement, // 現在の head, body をコピーしておきます。 oldHead = document.getElementsByTagName("head")[0].cloneNode(false), oldBody = document.body.cloneNode(false), // 新しいリクエストで取得する head, body の中身をそれぞれ格納します。 newElem = [null, null], // DocumentFragment の中に入ると head や body が消えてしまうので、予め分割しておきます。 texts = xhr.responseText.split(/<body[^>]*>/); // IE10からは Range#createContextualFragment が使えます。 // if の分岐後、やってることは同じです。 if (range.createContextualFragment) { newElem[0] = range.createContextualFragment(texts[0]); newElem[1] = range.createContextualFragment(texts[1]); } else { var div = document.createElement("div"); for (var i in newElem) { div.innerHTML = texts[i]; range.selectNodeContents(div); newElem[i] = range.extractContents(); } } // head の中身を入れ替えます。 // 一旦 head ごと削除し、コピーしておいた空の head を追加し、さらにその中に新しい中身を追加しています。 range.selectNode(document.getElementsByTagName("head")[0]); range.deleteContents(); root.appendChild(oldHead); document.getElementsByTagName("head")[0].appendChild(newElem[0]); // body の中身を入れ替えます。 // 同上 range.selectNode(document.body); range.deleteContents(); root.appendChild(oldBody); document.body.appendChild(newElem[1]); } }; xhr.send(); } })();
ここではiPhoneのiOS 5.0.1に偽装していますが、もちろん他のUAでも可能です。
キモは、インスタンスの生成に MSXML2.XMLHTTP を使っていること。
これを使うと XMLHttpRequest では不可能なUser-Agent書き換えができるようです。