Content-Type が設定された JS ファイルを提供するラック アプリですが、ブラウザでは Mimetype が「」であると表示されます
概要
ラックアプリがあります:
class Responder
def self.call(env)
path = env['PATH_INFO']
path = File.extname(path).blank? ? 'index.html' : path
extension = File.extname(path)
headers = {
'Content-Type' => Rack::Mime.mime_type(extension)
}
[200, headers, [ File.read(File.join(APP_ROOT, path)) ] ]
end
end
この目的は、/foo や /bar などのルートがindex.html で応答し、それ以外の場合は、ファイルが要求した .js または .css のリクエストがそのままパススルーされるようにすることです。
これをテストすると、ヘッダーに正しいコンテンツ タイプが設定されていることがわかります。これは、curl でも確認できます。
curl -i http://localhost:3000/foo
HTTP/1.1 200 OK
Content-Type: text/html
そして
curl -i http://localhost:3000/main.js
HTTP/1.1 200 OK
Content-Type: application/javascript
しかし、ブラウザでアプリケーションを表示しようとすると、JavaScript ファイルを呼び出すスクリプト タグが次のようなエラーで失敗します。
main.js:1 Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "". Strict MIME type checking is enforced for module scripts per HTML spec.
サーバーが「application/javascript」で応答していることをcurlが示しているのに、ブラウザはサーバーが「」のMIMEタイプで応答していると主張するのはなぜですか?
解決策
実際の Rack::Request / Rack::Response オブジェクトを使用して、MIME タイプを機能させることができました。
get '(*path)', to: ->(env) {
request = Rack::Request.new(env)
response = Rack::Response.new
extension = File.extname(request.path_info)
if extension.blank?
content_type = Rack::Mime.mime_type('.html')
filename = 'index.html'
else
content_type = Rack::Mime.mime_type(extension)
filename = request.path_info
end
response.header['Content-Type'] = content_type
response.status = 200
response.write File.read("public/app/#{filename}")
response.finish
}