外部APIを利用する際に、クロスドメイン対応でJSONPを扱いました。
その際、jQueryなしでゴリっと実装する必要があったため、調べたことのメモです。
jQueryの場合
jsonの場合とほぼ同様に扱えます。
$(function(){
$.ajax({
type: 'GET',
url: '/jsonp',
dataType: 'jsonp', // ここで設定
jsonp: 'jsoncallback', // コールバック関数のキーを設定
jsonpCallback: 'jsonpTestCallback' // コールバック関数名を指定
}).done((data) => {
console.log(data);
});
});
コールバック関数のキー、関数名が固定されていない場合は、jsonp、jsonpCallbackを指定しないでOKです。(?callback=jQuery1900...
が自動生成されます。)
JavaScriptの場合
axiosの拡張
axiosの拡張を使えば、手軽に実装できます。
axios-jsonp - npm
const axios = require('axios');
const jsonpAdapter = require('axios-jsonp');
axios({
url: '/jsonp',
adapter: jsonpAdapter,
callbackParamName: 'c' // optional, 'callback' by default
}).then((res) => {
console.log(res);
});
ただし、JSONPのコールバック名は指定できません。
コールバック関数名が固定されていない場合は、サクッとできてしまいますね。
ただ今回は、色々と制約があったためうまくいかず・・・ゴリっと実装することにしました。
ゴリっと実装する
こちらの手順を参考に、実装してみました。
JSONPをごりごり実装するときのポイント
const script = document.createElement('script');
script.src = '/jsonp';
const parent = document.getElementsByTagName('script')[0];
parent.parentNode.insertBefore(script, parent);
window.jsonpTestCallback = (res) => {
console.log(res);
};
概要
- scriptタグを動的に生成する
- scriptタグのsrcに、処理させたいサーバ側のファイルを指定する
- 処理させたいサーバ側のファイルはJavaScriptの関数になっているので、グローバルオブジェクトとしてJavaScriptから利用できる。
jsonpTestCallback
はグローバルオブジェクトになるので、window.jsonpTestCallback
としないと「そんなのないよ」と言われてしまいました。。
そのあたりを理解するために、こちらの記事が役に立ちました。
第11回 JSONP入門:これでできる! クロスブラウザJavaScript入門
まとめ
JSONPの場合(各方法共通で)、エラーが返却されないので、「一定時間結果が返ってこない場合はエラー処理をする」などの方法を追加する必要がありそうです。
jQueryやaxiosを利用する場合は、JSONもJSONPも、あまり違いを実感せずに使ってしまえますが、ゴリゴリやろうとすると、そういうことなのか!と改めて勉強になりました。