LoginSignup
2
3

More than 5 years have passed since last update.

Chromeエクステンションで、どうしてもJSONPでやりとりしないといけない場合の対処

Last updated at Posted at 2016-05-02

Chrome エクステンションは基本的に外部URLの参照を認めません。

http://からはじまる外部ファイルを使えるようにするにはmanifest.jsonにて定義してあげる必要があります。

ライブラリ

ダウンロードしてevent pageでで指定しておく

{
  "manifest_version": 2,
  "background":
    {
      "scripts": ["assets/js/jquery.min.js", "assets/js/floaty-color-clock-chrome.js", "assets/js/jp-prefecture.min.js"],
      "persistent": false
    }
}

アナリティクス

Content Security Policyの指定を追加しましょう。下記はプロジェクト自身が内部に保管しているjsファイルとアナリティクスの参照を許可しています。

  "content_security_policy": "script-src 'self' https://www.google-analytics.com; object-src 'self'"

書き方の詳細はこちら
CSP におけるポリシーのディレクティブ

こうなる

{
  "manifest_version": 2,
  "background":
    {
      "scripts": ["assets/js/jquery.min.js", "assets/js/floaty-color-clock-chrome.js", "assets/js/jp-prefecture.min.js"],
      "persistent": false
    },
  "content_security_policy": "script-src 'self' https://www.google-analytics.com; object-src 'self'"
}

http通信は拒否される

"content_security_policy"にてjsonPのドメインを指定すれば上手くいきそうですが、https以外の通信は拒否されちゃいます。

  "content_security_policy": "script-src 'self' http://example.com; object-src 'self'"

これは動かない。とは言え、参照しているデータがJSONを用意していない場合は無理くりでもJSONPで動かしたい。

JSONPから必要な部分だけを正規表現で取り出す

まずはmanifest.jsで、JSONPを受けとるドメインを許可しておきます。
"permissions": [ "activeTab", "http://www.drk7.jp/"],

こうなる


{
  "manifest_version": 2,
  "background":
    {
      "scripts": ["assets/js/jquery.min.js", "assets/js/floaty-color-clock-chrome.js", "assets/js/jp-prefecture.min.js"],
      "persistent": false
    },
  "permissions": [ "activeTab", "http://www.drk7.jp/"],
  "content_security_policy": "script-src 'self' https://www.google-analytics.com; object-src 'self'"
}

でJSONPを加工するjsファイルではこのように記述

function extractWeatherData (jsonp) {
    var re = /^[^{]*({.*})[^}]*$/; //正規表現を変数に格納
    var data = jsonp.match(re); // 正規表現をjsonpに対して実行

    if (data) {
        var weatherData = JSON.parse(data[1]);
        processWeatherData (weatherData);
    }
}

JSONPには下記のようにコールバックが記載されているのですが、その部分を除外してdataに格納しています。

drk7jpweather.callback ( //←この.callbackが不要
{
    "link": "http://www.drk7.jp/weather/xml/13.xml",
    "pref": {},
    "author": "気象庁",
    "title": "weather forecast xml",
    "pubDate": "Sun, 1 May 2016 18:00:02 +0900",
    "description": "気象庁の天気予報情報を XML で配信。1日1回 AM 6:00 ごろ更新。",
    "managingEditor": "drk7.jp"
    }
)

実行すると下記の部分がとれる

{
    "link": "http://www.drk7.jp/weather/xml/13.xml",
    "pref": {},
    "author": "気象庁",
    "title": "weather forecast xml",
    "pubDate": "Sun, 1 May 2016 18:00:02 +0900",
    "description": "気象庁の天気予報情報を XML で配信。1日1回 AM 6:00 ごろ更新。",
    "managingEditor": "drk7.jp"
    }

あとはjsonと同じですので、data[i]で取り出せます。

開発していたアプリが、自身のサーバー上では問題なく動いていたのに、chromeエクステンションでは動かなくなってしまった。サーバー上のコードとchromeエクステンションのコードは乖離させたくなかったのでこのようにしました。 同じように苦労している方の参考になれば。

// まあ、結局githubページの方がXHRを許可していなかったのでそれぞれに合わせた通信を書くハメになってしまったのですけど…。

開発していた拡張はこちら

Floaty Color Clock - Chrome ウェブストア
リポジトリ

スクリーンショット 2016-05-03 0.59.26.png

ぜひ使ってみてください。コードへの突っ込みもお待ちしております。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3