LoginSignup
3
2

More than 3 years have passed since last update.

jsonpの基本

Posted at

 はじめに

jsonpって言葉は聞いたことあるけど、jsonと何が違うのか全く理解していませんでした。
jsonと同じようにデータ取得できるだろうと思っていたら、全く取得できず、詰みました。
初めて違いを理解し、実際に使ったので、その備忘録です。

仕組み

jsonpとはjson with paddingの略だそうです。jsonpのurlを叩くと、下記のように返ってきます。


callback({"りんご":1,"ぶどう":2,"もも":3});

jsonpのurlを叩くと、scriptが実行されます。そのcallbackとして、データが返ってきます。

jsonとの違い

・jsonはjavascriptから生まれたデータ用フォーマットで、下記のような感じのデータを保持するものです。

{
  "りんご":1,
  "ぶどう":2,
  "もも":3
}

つまり、jsonはデータそのものだが、jsonpはjsの関数です。
jsonとjsonpはちょっと記述が違うだけ、という認識をすると混乱します。(私がそうでした。)

データ取得方法

違いはわかったけど、じゃあデータをどうやって取得するのがいいのでしょうか。
方法はいくつかあると思います。
ライブラリを使用して取得する方法が一番簡単で良いのかもしれませんが、今回はライブラリを使用しない方法を記載します。
(モジュールの一部を記載するので、もし参考にされる場合は、適宜classの中とかに入れる必要があります。)

ConfirmationAPI.js

let index = 0;
confirmSerialCode(url) {
  index++;
  const callbackName = `confirm${index}`;
  const random = Math.round(Math.random() * 10000000);
  return new Promise((resolve, reject) => {
    const $base = document.getElementsByTagName('script')[0];
    const $script = document.createElement('script');

    window[callbackName] = function (res) {
      resolve(res);
      document.body.removeChild($script);
    };

    $script.id = `jsonp${index}`;
    $script.async = true;
    $script.src = `${url}?callback=${callbackName}&cache=${random}`;
    $script.onerror = function () {
      reject('Request Error');
    };

    $base.parentNode.insertBefore($script, $base);
  });
}

index.js
this.confirmationAPI
  .confirmSerialCode(url)
  .then((res) => {
    console.log(res);
  })
  .catch((err) => {
    console.log(err);
  });

今回は、この関数が走って、callbackから返ってきた値をconsoleに出力しています。
また、2回走っても大丈夫なように、indexの連番を付与しています。
(連番をつける理由は、2回関数が実行されてしまって、コールバックが一緒だった時にうまく動かない可能性があるためです。)

最後に

これはjsonpで値をどう取得すればよいかわかっていなかった私自身の備忘録です。
もし使いやすいライブラリをご存知の方いらっしゃいましたら、教えていただきたいです。

3
2
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
3
2