Tumblr Dashboard でChrome + AutoPagerize を動かす
普段Chrome にAutoPagerize 入れて楽しんでますが,Tumblr Dashboard ではうまく動きません.
AutoPagerize の次ページロード方法を変えれば動くっぽいので,やってみました.
2014/05/22 追記 Chrome 35.0.1916.114 に対応
動かないのはなぜ?
そのままだと次のようなエラーで止まります.
Refused to display 'http://www.tumblr.com/dashboard/x/xxxxxxxxxxx' in a frame because it set 'X-Frame-Options' to 'deny'.
<iframe/>
を新たに作成- そこに次ページをロード
- 次ページのDOMを元のページに追加
- 作った
<iframe/>
を削除
ということをしているようで,X-Frame-Options:deny
を返すWebサイトでは当然ながら動きません.
昔は<iframe/>
ではなくXHR で次ページをロードしていたようなんですが...
なぜ <iframe/>
?
次ページがクロスオリジンなサイトだった場合に動きを止めたいが,XHR だとうまく実装できない
というのが理由だそうです.
Work with X-Frame-Options:deny on Chrome #3
req.responseType = 'document'
を指定してresponse.URL
を検証すればクロスオリジンかどうか判定できるが,イマイチ- PR時点のChrome では
response.URL
に望ましい値が入っていないため,信用できなかった
- PR時点のChrome では
- 当時のChrome では,なぜかクロスオリジンへリダイレクトできなかった
- 動作としては望ましいが...
- 理由がはっきりしないし将来動作が変わる恐れがあるため,これに依存したくない
ですって.
XHR 版をつかってみる
ここからが本題.
Work with X-Frame-Options:deny on Chrome #3
によると,<iframe/>
の代わりにXHR で実装したブランチを作ってくれていました.そっちを試してみます.
X-Frame-Options
によらず,動いてくれる期待が膨らみますね!
やることは
です.
1. ソースコードを取ってきて,最新版とマージする
github 上のコードは最新版ではないため,XHR 版ブランチを最新のものにします.
現時点での最新版は0.3.7.
わしのリブログ環境について にもマージ済みのfork がありましたが,メッセージファイルなどの差分が取り込まれてなくて...いちおう手元でやっときました.
(取り込まれてないと何が困るか確かめてない)
git clone https://github.com/swdyh/autopagerize_for_chrome.git cd autopagerize_for_chrome # 最新版コードで上書き (OSX の場合) cp -r ~/Library/Application\ Support/Google/Chrome/Default/Extensions/igiofjhpmpihnifddepnpngfjhkfenbp/0.3.7_0/* src git add . git commit -m "Merged 0.3.7 which was officially released" git checkout origin/xhr_with_webRequest -b xhr_with_webRequest git rebase master
Auto-merging src/manifest.json CONFLICT (content): Merge conflict in src/manifest.json Auto-merging src/background.js CONFLICT (content): Merge conflict in src/background.js Auto-merging src/autopagerize.user.js Automatic merge failed; fix conflicts and then commit the result.
やはりconflict しますね.
(ちょっと長いですが git diff
掲載します)
diff --cc src/background.js index 7579f4b,80132e5..0000000 --- a/src/background.js +++ b/src/background.js @@@ -157,3 -159,39 +157,42 @@@ function get(url, callback, opt) xhr.send(null) return xhr } ++<<<<<<< HEAD ++======= + + // Add X-XMLHttpRequest-Final-URL + var redirects = {} + chrome.webRequest.onBeforeRedirect.addListener( + function (details) { + redirects[details.requestId] = details.redirectUrl + }, + { urls: ["<all_urls>"], types: ["xmlhttprequest"] } + ) + chrome.webRequest.onHeadersReceived.addListener( + function(details) { + var name = 'X-XMLHttpRequest-Final-URL' + var value = (redirects[details.requestId] || details.url) + var add = true + for (var i = 0; i < details.responseHeaders.length; i++) { + if (details.responseHeaders[i].name === name) { + details.responseHeaders[i].value = value + add = false + } + } + if (add) { + details.responseHeaders.push({ name: name, value: value }) + } + return { responseHeaders: details.responseHeaders } + }, + { urls: ["<all_urls>"], types: ["xmlhttprequest"] }, + ["blocking", "responseHeaders"] + ) + chrome.webRequest.onCompleted.addListener( + function (details) { + if (redirects[details.requestId]) { + delete redirects[details.requestId] + } + }, + { urls: ["<all_urls>"], types: ["xmlhttprequest"] } + ) ++>>>>>>> use xhr with webRequest diff --cc src/manifest.json index 8c24254,e11b29d..0000000 --- a/src/manifest.json +++ b/src/manifest.json @@@ -1,32 -1,48 +1,68 @@@ { - "manifest_version": 2, - "homepage_url": "http://autopagerize.net/", - "content_scripts": [ - { - "js": [ - "extension.js", - "autopagerize.user.js" - ], - "matches": [ - "http://*/*", - "https://*/*" - ], + "background": { + "page": "background.html" + }, + "content_scripts": [ { + "js": [ "extension.js", "autopagerize.user.js" ], + "matches": [ "http://*/*", "https://*/*" ], "run_at": "document_end" ++<<<<<<< HEAD + } ], + "default_locale": "en", + "description": "A browser Extension for auto loading paginated web pages. AutoPagerize use in many web site, and provide efficiently web browsing.", + "homepage_url": "http://autopagerize.net/", + "icons": { + "128": "icons/icon128.png", + "16": "icons/icon16.png", + "32": "icons/icon32.png", + "48": "icons/icon48.png" + }, + "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfCTQFR5CUHBXm+UoYq3ihpQVyUujLq9l68O/Epw7lVZNwM6y/IdeiRNI4WFrxAlHaTdoFWW61gCuWyOR2Iy+/b2HjpHao7ssA+l4X6OcHVKuQypWjxEomWDmaZnz9LWQmsqOvQ4RltPDQtU/ym6DGHooRPpzG9EaYnSl7fM879wIDAQAB", + "manifest_version": 2, + "name": "AutoPagerize", + "options_page": "options.html", + "page_action": { + "default_icon": "icons/icon16.png", + "default_popup": "popup.html", + "default_title": "Autopagerize for Chrome" + }, + "permissions": [ "http://wedata.net/*", "tabs" ], + "update_url": "https://clients2.google.com/service/update2/crx", + "version": "0.3.7", + "web_accessible_resources": [ "error.html", "loading.html", "loading.gif" ] ++======= + } + ], + "description": "A browser Extension for auto loading paginated web pages. AutoPagerize use in many web site, and provide efficiently web browsing.", + "name": "AutoPagerize", + "permissions": [ + "webRequest", + "webRequestBlocking", + "tabs", + "http://*/*", + "https://*/*" + ], + "background": { + "page": "background.html" + }, + "options_page": "options.html", + "version": "0.3.5", + "icons": { + "16": "icons/icon16.png", + "32": "icons/icon32.png", + "48": "icons/icon48.png", + "128": "icons/icon128.png" + }, + "page_action": { + "default_title": "Autopagerize for Chrome", + "default_popup": "popup.html", + "default_icon": "icons/icon16.png" + }, + "default_locale": "en", + "web_accessible_resources": [ + "error.html", + "loading.html", + "loading.gif" + ] ++>>>>>>> use xhr with webRequest }
これを手動でマージしていきます.
# そのまま採用
git checkout --theirs src/background.js
manifest.json
もマージします.結果,こんな形.
{ "background": { "page": "background.html" }, "content_scripts": [ { "js": [ "extension.js", "autopagerize.user.js" ], "matches": [ "http://*/*", "https://*/*" ], "run_at": "document_end" } ], "default_locale": "en", "description": "A browser Extension for auto loading paginated web pages. AutoPagerize use in many web site, and provide efficiently web browsing.", "homepage_url": "http://autopagerize.net/", "icons": { "16": "icons/icon16.png", "32": "icons/icon32.png", "48": "icons/icon48.png", "128": "icons/icon128.png" }, "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfCTQFR5CUHBXm+UoYq3ihpQVyUujLq9l68O/Epw7lVZNwM6y/IdeiRNI4WFrxAlHaTdoFWW61gCuWyOR2Iy+/b2HjpHao7ssA+l4X6OcHVKuQypWjxEomWDmaZnz9LWQmsqOvQ4RltPDQtU/ym6DGHooRPpzG9EaYnSl7fM879wIDAQAB", "manifest_version": 2, "name": "AutoPagerize", "options_page": "options.html", "page_action": { "default_icon": "icons/icon16.png", "default_popup": "popup.html", "default_title": "Autopagerize for Chrome" }, "permissions": [ "webRequest", "webRequestBlocking", "tabs", "http://*/*", "https://*/*" ], "update_url": "https://clients2.google.com/service/update2/crx", "version": "0.3.7", "web_accessible_resources": [ "error.html", "loading.html", "loading.gif" ] }
rebase を完了しておしまい.
git add . git rebase --continue
2. chrome.webRequest パッチを適用 (2014/05/22 追記)
Chrome 35.0.1916.114 より,webRequest によるレスポンスヘッダーの修正時にコンフリクトするようになりました.
パッチを適用し,コンフリクトを解消します.
curl https://gist.githubusercontent.com/codeout/6835610480bbe5c6b981/raw/5a11706054c49d36a3a737f120815a217987b6a1/background.js | patch -p1
3. .crx
をビルドする
必要なツールセットを用意.
gem install crxmake
次のようにbuild.rb
を修正.
require 'rubygems' require 'crxmake' -CrxMake.zip( +CrxMake.make( :ex_dir => "./src", # private key は自動生成する - :pkey => "./autopagerize_for_chrome.pem", - :zip_output => "./autopagerize_for_chrome.zip", + :crx_output => "./autopagerize_for_chrome.crx", :verbose => true, :ignorefile => /\.swp/, :ignoredir => /\.(?:svn|git|cvs)/
最後にビルド.
./build.rb
autopagerize_for_chrome.crx
ができているはず.
4. Chrome に入れる
できたautopagerize_for_chrome.crx
を拡張機能ページにドラッグ&ドロップするだけです.
もとのAutoPagerize を無効化しておくのも忘れずに.
これでTumblr Dashboard でもAutoPagerize が動きます.幸せ.
注意
AutoPagerize を作った@swdyh さんもXHR には前向きっぽいのですが,まだ考え中のようです.XHR 版ブランチはきちんとテストされていない可能性もあります.
セキュリティに影響する変更なので, もう少し考えた上でマージするか決めようと思っています.
Work with X-Frame-Options:deny on Chrome #3
コードを眺めると別の仕組み(webRequest) でURL のスキーム/ホストが同じことを確かめているようですし,まあ大丈夫かなあと.しばらく使ってみようと思います.
ポートの確認はしてませんが...まあいいでしょうかね.