プログラマ探偵の事件簿:WindowsはJavaScriptのファイルをプレインテキスト(text/plain)だと思っている
JavaScriptのファイルの種類をWindowsがプレインテキスト(text/plain)だと思っていることで起こった事件の話である。
事件の始まり
TWSNMP FCにPWA機能を追加してWindows環境で最終テストをしていた時の話である。インストーラーを作ってWindows環境でPWAを画面を起動してみた。画面自体は特に問題もなく表示された。本題のPWAとしてインストールしてみようと思った時である。「インストールボタンがない」
開発者ツールで見えるものがある
助手の猫が天から「画面だけでは見えぬものがある、開発者ツールで見えるものがある」と言ったような気がした。Chromeの開発者ツールを開いてみると確かに
赤い色のエラーがでている。
手がかりは(text/plain)
エラーのメッセージを真面目に読んでみると、どうやら
service-worker.jsというPWAに関係したJavaScriptのファイルをプレインテキスト(text/plain)という種類(MIME type)だと思っていることが問題のようだ。
いつものようにGoogleさんに"go echo mime type"と聞いてみた。
WindowsだけがJavaScriptをtext/plainと思っているようだ
Googleに聞いた結果に
を見つけた。TWSNMP FCで利用しているWebサーバーのパッケージechoに寄せられた質問である。
読んでみると今回の問題とまったく同じことが起こっている。
このサイトにいくつか興味深い切り分け方法が書いてあるので試してみた。
TWSNMP FCの応答を確認してみる
本当にTWSNMP FCがJavaScriptの種類がtext/plainという応答を返しているか確認してみた。
Windows版では
% curl -IXGET http://192.168.1.25:8080/pwa/service-worker.js
HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 1357
Content-Type: text/plain; charset=utf-8
Last-Modified: Mon, 11 Apr 2022 11:23:58 GMT
Vary: Origin
確かにContent-Type: text/plain;と言っている。
Mac OS版も試してみた。
% curl -IXGET http://localhost:8080/pwa/service-worker.js
HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 1357
Content-Type: application/javascript
Last-Modified: Mon, 11 Apr 2022 11:23:58 GMT
Vary: Origin
Date: Sat, 16 Apr 2022 21:36:33 GMT
JavaScriptをapplication/javascriptと応答している。
助手の猫が「この違いが問題の元である」と言ったような気がする。
OSが認識しているJavaScriptのMIMEタイプを確認する
先のサイトに書いてあったOS上でMIMEタイプを確認するテストプログラムを試してみた。
package main
import (
"fmt"
"io/ioutil"
"mime"
"net/http"
"os"
"path/filepath"
)
func main() {
if len(os.Args) < 2 {
fmt.Println("Need a filename")
os.Exit(1)
}
name := os.Args[1]
fmt.Println("mime.TypeByExtension:", mime.TypeByExtension(filepath.Ext(name)))
content, err := ioutil.ReadFile(name)
if err != nil {
fmt.Println(err)
os.Exit(2)
}
fmt.Println("http.DetectContentType:", http.DetectContentType(content))
}
のプログラムである。
Mac OSでは、
のように拡張子の判定でJavaScriptとなっている。
Windowsでは
どちらもtext/plainと認識している。これが問題の元凶のようだ。
WindowsにJavaScriptのファイルの種類を教えて解決
先のサイトに解決策がいくつか書いてある。Windowsのレジストリを変更する方法の他にGO言語のmimeパッケージのファイルのmimeタイプを追加する関数を使う方法がある。この関数を使う方法を試してみた。
mime.AddExtensionType(".js", "application/javascript")
の1行をWebサーバーの初期化処理に追加するだけである。
「jsという拡張子はJavaScriptだよ」とWindowsに教えるようなものだ。
この結果、
のようにWindowsでもPWAをインストール可能になった。
PWAとして
なぜWindowsがJavaScriptをプレインテキスト(text/plain)と思っているのかは永遠の謎である。もしかすると何かのソフトをインストールした環境では、JavaScriptをプレインテキスト(text/plain)と思っていないのかもしれない。
開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。 ソフトウェアのマニュアルをnoteの記事で提供しています。 サポートによりnoteの運営にも貢献できるのでよろしくお願います。