Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

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

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away