Google Drive上の画像直リンクが動作しない!!
数日前から、自分の作成してるアプリにて、Google Drive上の画像(リンクを知っていればアクセス可能)に対する直リンク画像を使ってるものに於いて、画像が表示されなくなる現象が発生しました。この問題点と解決策についてまとめてみます。
今回の解決手法は画像に対してのみ有効であるので、動画や音声ファイルに対しては依然として直リンクで呼び出すことが出来ません。
ドライブファイルへの直リンクとは?
Google Drive上のファイルは実はプレビューだけじゃなく、直リンクで利用する事が昔から出来ています。PDFのファイルをリンクを開かせてからダウンロードさせるのではなく、リンククリックでダイレクトダウンロードであったり、ウェブアプリの画像などに於いて画像を直接表示させてみたりといったことが可能です。
ちょっと変形したURLにしてあげる必要があるのですが、これまではGoogle Drive Direct Link Generatorなどで表示されるような、以下のURL形式で画像の呼び出しが可能でした
1 2 3 4 5 |
//ダウンロードさせるリンク https://drive.google.com/uc?export=download&id=1RGkiuML-0RgLT6IUKsJIEqm3yCP5sWrs //ブラウザ上で表示させるリンク https://drive.google.com/uc?export=view&id=1RGkiuML-0RgLT6IUKsJIEqm3yCP5sWrs |
こうする事で、HTML上のimgのsrcに指定したり、aタグのhrefに指定して直接リソースにアクセスが可能になります。しかし、ファイルに対しては依然として有効なのですが、問題は画像がこれで表示できなくなったのです。ちなみに、画像を直リンクで使う場合は通常、ダウンロードさせるリンクをimgのsrcに指定します。
今回検証用ファイルとしてはこちらを用意しました。
※どうやら画像だけじゃなくサウンドファイルなんかも再生できなくなってかなり多数の人が困ってるようです。
原因と対策
発生原因
以下のような簡単なウェブアプリとして、画像の直リンクを指定したものを表示させてみたのですが、403でアクセスが拒否されて使えなくなったというのが今回の症状。この原因について、stackoverflowに記述されていた内容によると、画像リクエストに対して以下の2つのリクエストヘッダーがあるもの(デフォルトで付加される)が送られてるものについて、拒否が始まってるとのこと。CORSの問題っぽいですね。直接的に関係のある変更と言われているのはこちらのGoogleのエントリー内容のようです。
1 2 |
sec-fetch-mode: no-cors sec-fetch-site: cross-site |
故に、プログラム等でGETリクエストを送るようなケースでもこの症状が当然出てきています。ブラウザのURLで直接叩いた場合はこれが無いので素直にダウンロードされるわけです。この症状は2024年1月10日から始まってるようで、HTML内にダイレクトリンクを入れても画像を呼び出せなくなってるのです(もちろん、Google Drive以外のサーバの画像は直リンクを入れても全く問題ない)。
この問題に対するIssueTrackerがあげられています。
1 2 3 4 5 6 7 8 9 |
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <img src="https://drive.google.com/uc?export=download&id=1RGkiuML-0RgLT6IUKsJIEqm3yCP5sWrs" alt="直リンク" /> </body> </html> |
図:発生した403エラー
Googleからの迂回策
Issue Trackerにて、当初の提示策が以下のようなものが投稿され、ステータスを「修正しない」として投稿し、ややスレッドでは炎上気味になっています。意図された動作ということのようですが、解決策というものが
- 対象のファイルをダブルクリックで開く
- 右上の「︙」をクリックし、新しいウィンドウで開くをクリック
- 新しいウィンドウでまた右上の「︙」をクリックして、アイテムを埋め込むをクリック
- iframeの埋め込みタグが出てくるので、それをコピーする
- 対象のHTMLに貼り付ける
といったもので、ユーザが意図したものとはだいぶ異なる回答になっています。iframeのサンドボックスで貼れば良いだろうという解決策は、スレッドで求めてる直接的にリソースとして使うものとは異なるだけじゃなく、プログラム的に使うこともこれでは出来ないのでかなり無理のある内容です。おまけにすごく面倒な手順です。
その後再度、割り当て済みステータスに変えており、どうなってしまうのか・・・
図:見られれば良いというわけではないのですが
対策法その1
既に挙げられてるいくつかの手法があるのですが、少なくともそのうちの1つである以下のようなURL形式に変更してHTMLのimgタグに入れる手法については自分の場合、動作しませんでした。確かに画像は開かれるのですがリダイレクトが働き、別のURLに変更され、またそのリダイレクト後のURLであっても403エラーで拒否されました。この手法については、こちらのページで掲載されています。
1 2 |
//ダメだった代替策 https://drive.google.com/uc?id=1RGkiuML-0RgLT6IUKsJIEqm3yCP5sWrs&.JPG |
そこでStackOverflowを探ってみたところ、1年前ほどのエントリーですが、以下のようなURL形式にすることで回避してこれまで通り、画像を直リンクで利用できることがわかりました。
1 2 |
//利用できた代替策 https://lh3.google.com/u/0/d/1RGkiuML-0RgLT6IUKsJIEqm3yCP5sWrs |
これであれば、HTML内のimgタグのsrcに指定したり、Vuetifyのdrawerなどの背景画像のsrcに指定してもばっちり動作しました。https://lh3.google.com/u/0/d/の後に画像ファイルのIDをつなげればオッケーです。よって、以下のようなHTMLならば問題なく動作します。但し、このURLの場合、Googleアカウントでサインインしておく必要性がありますので、完全な回避策ではありません。。
1 2 3 4 5 6 7 8 9 |
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <img src="https://lh3.google.com/u/0/d/1RGkiuML-0RgLT6IUKsJIEqm3yCP5sWrs" alt="直リンク" /> </body> </html> |
図:エラーが出ず画像もしっかり出てきました
対策法その2
前述の別の形式のURLを利用する方法とはまた別の、サムネイル表示する為のURLに対して、リクエストを投げる方法も編み出されています。
1 2 |
//オッケーだった手法その2 https://drive.google.com/thumbnail?id=1RGkiuML-0RgLT6IUKsJIEqm3yCP5sWrs&sz=w1000 |
サムネイル用のURLに画像ファイルのIDをつなげ、さらにsz=w1000とすることで、widthが1000のサムネイルという形で出力が可能です。szが無い場合には標準のサムネイル画像のサイズになってしまうので、小さいものが出力されます。
こちらのURLの場合は、Googleアカウントにログインしておく必要性が無いので、こちらのほうが実用的と言えます(画像サイズの指定があるのが面倒ですが)。こちらのページにサンプルがあります。
※但しこの手法は画像ファイルに対してだけ有効だと思われるので、動画ファイルや音声ファイルの呼び出しには効果がないと思われます。
スライドの埋込は?
Googleスライドなどをウェブに公開時に表示されるiframe埋め込みのタグをそのままGoogle Apps Scriptのウェブアプリケーション上に貼り付けてみましたが、こちらについては特に問題もなく表示がされました。
よって、動画や音声ファイルはスライドに貼り付けて公開といったようなちょっとトリッキーな手法を利用するしか回避方法が現在ありません。
1 |
<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vRgxje6hMf0CgiP4rc0dz7hsHKqr3Rbqatqmb0tqgnpwkklI3ZSK-DP_3VL81leHusi2Hf6JKwKjMjp/embed?start=false&loop=false&delayms=3000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe> |