[前回の記事]
前回の記事で、見事NuxtでスプレッドシートをDBの代わりとして使えるようになりました🎉🎉🎉。
そう...PCでは...。
実際にngrokとかで試していただくとわかるのですが、この方法だとモバイルからアクセスしたときに機能しません。 少なくとも僕のiPhone8 + Chrome構成ではアクセスできません...。
今開発しているspaces.bzでも、ローカル開発で自動テストも通ってリリース、としたらモバイルでアクセスできず「ぐぬぬ」となったのはよい思い出。
ということなので、モバイルでもスプレッドシートのデータを表示するぞ💪。
何がだめだったのか
PCでできてモバイルでできないとは何事か。一体何が起きているのでしょう。 axiosでエラーハンドリングしてみると、モバイルでは「Error: Network Error」と表示されます。こいつだ👮。
「axios network error mobile」「axios network error gas」など色々検索してみると、どうやらCORS周りが怪しいようです。 簡単に言えばAccess-Control-Allow-Origin
に*
とかを設定するのではなく、ちゃんとOriginを設定しろとのこと。 が、GASはヘッダー情報をいじれない...。
ということで、jsonp
を利用してCORSを回避する方法が情報としては多かったです。
- gasでつくったAPIをAXIOSで読み込めない。
- javascript - Cross-domain requests stopped working due to no `Access-Control-Allow-Origin` header present in the response - Stack Overflow
- モバイル環境でNetwork Errorでハマった。「EC2にDocker Caddy Laravel, S3にVuejsの構成」 #PHP - Qiita
今回はJSONPで情報を取得できるようにしてみます。
やること
- Nuxtのデータ取得をJSONPバージョンに更新
- GASのレスポンスをJSONPバージョンに更新
Nuxtの更新
まずはNuxt側の更新をしていきます。最初にaxios
の中でjsonp
を使えるようにしてくれるaxios-jsonp
を導入します。
ちなみにaxios
自体はjsonp
をサポートしていないようです。
axiosのオプションにadapter
として指定します。
Nuxt側の準備はこれで以上です👏。
次は、GASを更新します。
GASの更新
JSONPが何者かっていうと、JSONをCallback関数の引数として返すものです。
通信のイメージは次のとおりです。
- リクエスト側:このCallback関数にデータちょうだーい
- レスポンス側:データをCallback関数の引数にして送るよー
- リクエスト側:ありがとー。あとはこっちのCallback関数で処理するぞー
axios-jsonp
はリクエスト側の「callback関数を自動で生成する」「axiosっぽくcallback関数で処理する」などをやってくれるライブラリということですね。
なのでGAS側もその挙動に合わせてコーディングし直します。更新する箇所はコード.js
のdoGet
関数の部分だけです。
以上です。ちょっと説明。
doGet
関数は引数e
を利用可能です。event
ですね。ここからURLのクエリパラメーターを取得できたりします。
axios-jsonp
はクエリパラメーターcallback
でcallback関数を指定してくれるので、それを取得してレスポンスで返却するためにe
を追加します。
こんな感じ。
この部分でcallback([{'id': '1', ...}, ...])
みたいなレスポンスを生成しています。 これをaxios-jsonp
が受け取っていい感じにデータ[{'id': '1', ...}, ...]
を扱ってくれるんですね。
最後にJSONPはJSONとは異なり、MimeTypeをJAVASCRIPT
にする必要があるので更新します。
以上でGASの更新も完了です。👏 WebAppをデプロイしてモバイルでもデータを表示できるか試してみましょう。
小噺:デプロイは「デプロイを管理」から
また新しいデプロイからWebAppを作成するとURLが前回から変わってしまいます。 「デプロイ」>「デプロイを管理」からバージョンアップがおすすめです。
まとめ
前回、スプレッドシートをDB代わりとして使えるようになったかと思いきや、まさかのモバイルで使えない問題... 今回はJSONPを使うことでモバイルでもスプレッドシートのデータを表示できました。
これでPCとモバイルの両方でデータを表示できたし一見落着...と思いきや... spaces.bzでもこの方式でサービス提供していたのですが、いまは別のやり方にしてます。