検索プレビュー-Chromeの拡張機能

拡張について



この拡張機能により、Googleで検索結果のサイトを表示できるようになり、情報の検索と処理にかかる時間が大幅に短縮されます。



画像



背景



Googleがインスタントプレビュープロジェクトを閉じた後、必要な情報の検索に時間がかかり始め、タブと神経が開きました。

その後、私はこの状況を修正し、私の生活を楽にする小さな拡張子を書くことにしました。



開発



Google ChromeはHTML5テクノロジー(iframeサンドボックス)をサポートしていたため、拡張機能を実装するのは難しくなく、ある夜にプロトタイプが作成されました。 私は確かにこれに満足していましたが、インスタントプレビューの閉鎖の犠牲者であった他の人々にとっては悲しかったです。 したがって、私はオープンアクセスで拡張機能を投稿することにしました。



拡張機能自体は、iframeの任意のページをロードする機能に基づいていましたが、sandbox属性を使用すると、javascriptを無効にしてメインウィンドウをリダイレクトできました。 iframeから次のコードを実行することは不可能でした。



top.location = <redirect_url>;
      
      







一部のサイトでiframe「X-Frame-Options」での表示を禁止する見出しが表示されるまで問題はありませんでしたが、それでも問題の半分でしたが、新しいバージョンのGoogle Chromeは保護されたサイトに保護されていないコンテンツをロードすることを禁じました、つまり iframe httpを含むhttpsサイトにデータを埋め込むことは不可能でした。 その結果、ほとんどのサイトはiframeに表示されませんでした。 ユーザーは文句を言うようになり、拡張機能はそのタスクに対処できず、検索結果からサイトに直行しなければならず、すべてが最初に戻りました。



ソリューションを検索する


しかし、これは私を止めるものではありませんでした。この問題を解決することは興味深いことでした。 Webプロキシを使用するために最初に思いついたのは、つまり iframeでサイトから直接データをダウンロードするのではなく、httpsセキュアプロトコルを使用するWebプロキシを介して、安全でないコンテンツの問題を解決し、WebプロキシはX-Frame-Optionsヘッダーをカットできました。



ウェブプロキシの開発に時間を無駄にしたくありませんでした。問題を迅速に解決する必要がありました。 少しグーグルでこのgoogle-proxyスクリプトに出会いました-これはPythonで書かれたappengineのWebプロキシです。 それをインストールして拡張機能の新しいバージョンを展開した後、私は長い間問題を忘れていませんでした。 しかし、問題は再び無料のappengineクォータがないという形で発生し、Webプロキシ用にいくつかのミラーを作成する必要がありました。 4つのミラーを作成したので、すべてが正常であるように見えましたが、拡張機能のレビューで、クォータが不足しているというエラーが再びあったと私に書きました。 appengineでは、クォータは24時間ごとにリセットされます。 私はクォータの拡張を使用していますが、それでも十分ですが、世界の別の地域の住民にとっては、クォータはすでに使い果たされています。



独自のWebプロキシ


少し考えてから、Webプロキシの作成に時間を費やすことにし、Go言語を選択しました。 Go言語を学ぶのに少し時間がかかりました その前に、教育目的で小さなスクリプトを作成しました。 しかし、GoでWebサーバーの開発に遭遇することはありませんでした。 ドキュメントを読んで、 Webツールとしてgorillatoolkit 、つまりgorilla / mux routerを選択した 。 ルーターの作成は非常に簡単です。



 r := mux.NewRouter() r.HandleFunc("/env", environ) r.HandleFunc("/web_proxy", web_proxy.WebProxyHandler) r.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir(staticDir)))) r.Methods("GET")
      
      







さらに、リンクとアドレスを置き換えるために、htmlのクリーニングではgokogiriライブラリを選択しました。これはlibxmlのシェルです。 Webプロキシスクリプトですべてのアドレス(URL)を取得する必要がありました。 次に、スクリプトタグを含むDOMから完全に削除することにより、いくつかのタグを無効にしました。 インタラクティブなプレビューサイトは必要ありません。 CSSも以来処理されています URL画像、フォントなどがあります。



DOMをバイパスすると、タグのこのようなマッピングが判明し、タグに対応する関数が呼び出されます。



 var ( nodeElements = map[string]func(*context, xml.Node){ // proxy URL "a": proxyURL("href"), "img": proxyURL("src"), "link": proxyURL("href"), "iframe": proxyURL("src"), // normalize URL "object": normalizeURL("src"), "embed": normalizeURL("src"), "audio": normalizeURL("src"), "video": normalizeURL("src"), // remove Node "script": removeNode, "base": removeNode, // style css "style": proxyCSSURL, } xpathElements string = createXPath() includeScripts = []string{ "/js/analytics.js", } cssURLPattern = regexp.MustCompile(`url\s*\(\s*(?:["']?)([^\)]+?)(?:["']?)\s*\)`) )
      
      







HTMLフィルタリング。

 func filterHTML(t *WebTransport, body, encoding []byte, baseURL *url.URL) ([]byte, error) { if encoding == nil { encoding = html.DefaultEncodingBytes } doc, err := html.Parse(body, encoding, []byte(baseURL.String()), html.DefaultParseOption, encoding) if err != nil { return []byte(""), err } defer doc.Free() c := &context{t: t, baseURL: baseURL} nodes, err := doc.Root().Search(xpathElements) if err == nil { for _, node := range(nodes) { name := strings.ToLower(node.Name()) nodeElements[name](c, node) } } // add scripts addScripts(doc) return []byte(doc.String()), nil }
      
      







CSSフィルタリング:



 func filterCSS(t *WebTransport, body, encoding []byte, baseURL *url.URL) ([]byte, error) { cssReplaceURL := func (m []byte) []byte { cssURL := string(cssURLPattern.FindSubmatch(m)[1]) srcURL, err := replaceURL(t, baseURL, cssURL) if err == nil { return []byte("url(" + srcURL.String() + ")") } return m } return cssURLPattern.ReplaceAllFunc(body, cssReplaceURL), nil }
      
      







また、Cookie、X-Frame-Optionsヘッダーを除外し、24時間のキャッシュを設定しました。

Webプロキシをherokuにインストールすることを決定しました。これもopenshiftについて考えましたが、私が知る限り、接続数に制限があります。



heroku + Goのソリューションは私に完全に適しており、3月以降、飛行が正常であると言っているので、クォータに問題はありません。



延長


拡張機能はうまく機能し、ズームボタンが追加されました。 ズームについてはまだその話がありましたが、ズームまたはメインウィンドウを変更するたびに、新しい方法に従ってiframeサイズを計算するたびに、間違った方法でCSS変換スケールをiframeに適用しました。 しかし、その後、かなり簡単な解決策が浮上しました。



 zoom: <zoom>%;
      
      







このズームは、document.documentElementのWebプロキシページに適用されます。 しかし、私はそこで止まらず、探しているもののプレビューで十分なハイライトを持っていませんでした。 キーワード強調アルゴリズムは単純に選択されました-サブストリング内のストリングを検索します。 これは単純な場合にはうまく機能しましたが、テキストに異なる語尾をもつ単語が表示されると、検索は機能しませんでしたし、さらに悪いことに、間違った単語で短いサブストリングが見つかりました。



全文検索のハイライト


ソリューションは、ポーターのステマーの形で見つかりました。つまり、 スノーボールの形での実装、 xregexpライブラリー、Unicodeアドオンも、 ステマーに送信されるトークンの作成に使用されました。 私はステマーの言語を決定するアルゴリズムを作成しませんでしたが、異なる言語のステマーをトークンに適用し、成功した場合、ステマーはtrueを返しました。



ツール


言語としてcoffeescriptを選択しました。Pythonが好きですが、欠点があります。 Gulpは、開発バージョンと製品バージョンの構築を担当します。 非常にシンプルなビルダー、多数のプラグイン。 gulpfile.coffeeの学習と仕上げに費やした時間のほんの一部ではありませんが、これはアセンブリの速度によって正当化されます。 アセンブリbrowserifyにも関与しています。



PSああああ! 拡張リンクをほとんど忘れていました。



質問、提案?



All Articles