LoginSignup
__sil
@__sil

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

scriptタグのsrc属性への指定ではCGIが動かない理由が知りたいです。

CGIの挙動についての質問です。

APIキーの隠蔽について調べていたときに、このQiitaの投稿に行き当たりました。
Google Maps API キーをHTMLから隠す方法

詳しくは当該記事をご覧いただければと思うのですが(そこまで長い記事ではありません)、この記事で紹介されている手法は、「リクエストを受けると、JavaScriptコード文字列を返すCGIを用意。クライアントサイドでfetch APIを使ってこのCGIにリクエストを飛ばし、返ってきたコード文字列をeval()で実行」というものです。

私はここで、スクリプト側からリクエストを飛ばしてeval()しなくても、scriptタグで外部スクリプトとして指定しておけばブラウザが勝手にリクエストから実行までやってくれるのではないかと考えました。

つまり、

fetch("/cgi-bin/getapijs.py").then(res=>{
    return res.text();
}).then(mytext => {
    eval(mytext);
});

と書くところを、

<script src="/cgi-bin/getapijs.py"></script>

と書くことができそうに感じた次第です。

そこで、どうしてscriptタグが使えないのかという旨の質問のコメントをしたところ、
筆者さんから

JAVAScript のコードを取得するためには、まず python が動く必要があります。python が動くためには直接 script タグではダメなのです。

というお返事をいただきました。

ただ、それでもscriptタグではPythonが動かない理由が、どうにも理解できませんでした。
なぜfetchによるリクエストとscriptタグによる外部リソースリクエストでCGIの挙動が異なるのか、ご教示いただきたいです。

0

2Answer

ブラウザが動かせるスクリプトはJavaScriptだけです。
参考にされた記事はPythonで「JavaScriptを返すCGI」を書いているだけだと思われます。

0

Comments

  1. @__sil

    Questioner
    それはわかっています。

    fetchによるリクエストと、scriptタグによる外部リソースリクエストでCGIの挙動が違う(違うんですよね?)理由が知りたいのです。
  2. @__sil

    Questioner
    ええと、fetchを使ってリクエストしたとき、CGIはJavaScriptコード文字列を返すのですよね?
    scriptタグによる外部リソースリクエストの際には、サーバーは何を返すのですか?
    私はfetchリクエストのときと同じくJavaScriptコード文字列が返されると考えたのですが、そうではないということなんですよね。

    scriptタグを記述したとき、サーバーが返すものは何で、なぜサーバーの返すものがfetchリクエストの場合と違うのかが知りたいです。
  3. すみません、意図を勘違いしていたようです。scriptタグで読み込んだときにContent-Typeが正しくtext/javascriptとして読み込まれていれば問題ないはずです(違いはないはずです)。Content-Typeが異なっていればヘッダーの書き方の問題かもしれません。
  4. @__sil

    Questioner
    ありがとうございました。
    筆者さんにもう一度問い合わせてみようと思います。

元記事の筆者さんが CGI を理解していないように見受けられます。 CGI で Python が動くのはサーバ側の都合であって、ブラウザ側は関知しません。 GET /cgi-bin/getapijs.py して JavaScript コードが返ってくるならそれは問題なく読み込めます。よって <script src="/cgi-bin/getapijs.py"></script> でも動くと思います。

ところで悪用しようと思えば /cgi-bin/getapijs.py を勝手に使うこともできるわけで、 API キーをページに埋め込むのと大差ない気はします。


@_y_s さん、

MDNを見てください。JavaScript以外の外部スクリプトは無効です。

/cgi-bin/getapijs.py は Content-Type: text/javascript で JavaScript コードを返すのですから、有効な JavaScript として <script> タグで読み込めますよ。

0

Comments

  1. @__sil

    Questioner
    すみません、確認させてください。
    まず、「スクリプトからfetchでCGIにリクエストした場合と、scriptタグをブラウザが解釈した結果CGIにリクエストが飛んだ場合とで、サーバーが返すデータは同じ」という理解でいいですか?
  2. 同じです。それぞれの場合で飛ぶ GET リクエストはヘッダの値が多少異なるだけです。サーバ側でそれを見分けるようにでもしない限りは同じデータを返します。
  3. @__sil

    Questioner
    ありがとうございます。

    もともとの質問からは離れますが、ついでに「悪用しようと思えば/cgi-bin/getapijs.pyを勝手に使うこともできる」という点についても伺ってよろしいでしょうか。

    私がこの記事を読んだとき、
    「bin/getapijs.pyは事実上https://maps.googleapis.com/maps/api/js?key=API_KEYへの透過的なラッパーだから、外部からbin/getapijs.pyにアクセスすればAPIにタダ乗りできてしまうんじゃないか?
    と思いました(透過的なラッパーという表現が不自然なのはご勘弁を)。
    APIキーは隠せているけど、リファラーか何かで制限しないとむしろAPIキーを知らなくとも使い放題の状態になってしまうのではないかと…

    uasiさんがおっしゃった「勝手に使うこともできる」というのはこれと同じ意味でしょうか?
  4. はい、おっしゃる通りです。
  5. @__sil

    Questioner
    ありがとうございます。
    お世話になりました。

Your answer might help someone💌