Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mime: incorrect mime-type for .js files on windows 10 (text/plain instead of application/javascript) #32350

Closed
kjk opened this issue May 31, 2019 · 26 comments · Fixed by ferrmin/go#381
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done. OS-Windows
Milestone

Comments

@kjk
Copy link

kjk commented May 31, 2019

What version of Go are you using (go version)?

$ go version
go version go1.12.5 windows/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\kjk\AppData\Local\go-build
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=C:\Users\kjk\go
set GOPROXY=
set GORACE=
set GOROOT=C:\Go
set GOTMPDIR=
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=C:\Users\kjk\src\apps\offdocs\go.mod
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\kjk\AppData\Local\Temp\go-build840166758=/tmp/go-build -gno-record-gcc-switches

What did you do?

Consider this program:

package main

import (
	"fmt"
	"mime"
)

func main() {
	ct := mime.TypeByExtension(".js")
	fmt.Printf("ct: %s\n", ct)
}

https://play.golang.org/p/JTVjWc9xMDE

What did you expect to see?

Mime-type for .js files should be application/javascript on all platforms.

What did you see instead?

On Linux it returns ct: application/javascript

On my latest Windows 10 it returns ct: text/plain; charset=utf-8

This also affects Content-Type returned by http.ServeFile() for .js files.

This is because in src\mime\type.go:

func initMime() {
	if fn := testInitMime; fn != nil {
		fn()
	} else {
		setMimeTypes(builtinTypesLower, builtinTypesLower)
		osInitMime()
	}
}

On Windows osInitMime() reads info for additional extensions from registry and over-writes mime-type for .js files.

Note: it's possible this won't repro on every version on Windows.

Reversing the initialization order should fix it:

osInitMime()
setMimeTypes(builtinTypesLower, builtinTypesLower)
@mvdan mvdan added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows labels May 31, 2019
@slrz
Copy link

slrz commented May 31, 2019

Reversing the order would be a pretty heavy-handed fix. Local system configuration should have precedence over the builtin defaults.

Does this issue reproduce on a clean Windows install?

@hdm
Copy link

hdm commented Aug 27, 2019

This issue started to appear out of the blue on a Windows 10 1903 install (go 1.12.9).

@hdm
Copy link

hdm commented Aug 27, 2019

A terrible work-around:

var builtinMimeTypesLower = map[string]string{
	".css":  "text/css; charset=utf-8",
	".gif":  "image/gif",
	".htm":  "text/html; charset=utf-8",
	".html": "text/html; charset=utf-8",
	".jpg":  "image/jpeg",
	".js":   "application/javascript",
	".wasm": "application/wasm",
	".pdf":  "application/pdf",
	".png":  "image/png",
	".svg":  "image/svg+xml",
	".xml":  "text/xml; charset=utf-8",
}

func staticFileGetMimeType(ext string) string {
	if v, ok := builtinMimeTypesLower[ext]; ok {
		return v
	}
	return mime.TypeByExtension(ext)
}

@mattn
Copy link
Member

mattn commented Aug 27, 2019

On Windows7, mime type of .js is application/javascript:

Sorry, it may not be default configuration.

C:\>reg query HKCR\.js /v "Content Type"

HKEY_CLASSES_ROOT\.js
    Content Type    REG_SZ    application/javascript

@hdm
Copy link

hdm commented Aug 27, 2019

Interesting, I wonder what is changing this. Thanks for the pointer.

C:\>reg query HKCR\.js /v "Content Type"

HKEY_CLASSES_ROOT\.js
    Content Type    REG_SZ    text/plain

@mattn
Copy link
Member

mattn commented Aug 27, 2019

As a result that I swimed in internet for 10 minutes, I figure out this value of the registory key seems to be possibly changed by some text editor or casual confguration.

https://timothytocci.com/tag/registry/ (text/plain)

https://www.jianshu.com/p/a443991462d7 (application/x-javascript)

And it is not registered in default on Windows 10. I think this should not be set from registory. Or should be non-overwritable.

@gopherbot
Copy link

Change https://golang.org/cl/191917 mentions this issue: mime: do not change initial configuration for mimeTypes

@mattn
Copy link
Member

mattn commented Sep 6, 2019

builtinTypesLower is safe. it is not overwritable. mime.types or registory is NOT safe. This can be added to mimeTypes easily. (ex with installing text editor on Windows). So cl191917 disable overwrite to mimeTypes from mime.types or registory. What about this?

@lafriks
Copy link

lafriks commented Nov 25, 2019

Currently this issue prevents service worker to load as browsers block it if it's content type is not JavaScript

@zekroTJA
Copy link

Hey, just wanted to mention that I have created a little tool to check if the problem is also caused on your machine and to fix the issue by setting the mentioned registry key to the expected value application/javascript. Just if someone might be interested.

https://github.com/zekroTJA/go-win-mime-fix

@capraynor
Copy link

capraynor commented May 29, 2020

Hi
I think that this is caused by the registry settings in windows 10.

If you are looking for a temporary solution, please import the following registry items:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.js]
"Content Type"="text/javascript"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.js]
"Content Type"="text/javascript"

IMHO this one is caused by system, but not golang itself.

Did I miss something?

@iwdgo
Copy link
Contributor

iwdgo commented Jul 15, 2020

There seems to be some evolution.
On Windows 10 latest, registry key only defines the file type and no Content Type appears.

%GOPATH%\mime>ver

Microsoft Windows [Version 10.0.18363.959]

%GOPATH%\mime>go version
go version go1.14.5 windows/amd64

%GOPATH%\mime>reg query HKCR\.js

HKEY_CLASSES_ROOT\.js
    (Default)    REG_SZ    JSFile

HKEY_CLASSES_ROOT\.js\PersistentHandler

%GOPATH%\mime>go run jsmimetype.go
ct: text/javascript; charset=utf-8

These values appear in line with Mozilla documentation.

@sidecut
Copy link

sidecut commented Sep 28, 2020

Hi
I think that this is caused by the registry settings in windows 10.

If you are looking for a temporary solution, please import the following registry items:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.js]
"Content Type"="text/javascript"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.js]
"Content Type"="text/javascript"

IMHO this one is caused by system, but not golang itself.

Did I miss something?

The requirement of the mime package should be to correctly ascertain the mime type of common files, regardless of Windows registry settings. If a web server can't properly serve up a js file, that's a major facepalm right there.

For .js, .html, and .css, the code should return the expected mime type on Windows if the Content Type registry value is missing. Those three are sensible special cases for fallbacks in case of missing values in the Windows registry.

@oliverjanik
Copy link

Same problem persists in Win 10 with go 1.15.3

@dvaldivia
Copy link

Same problem on Go 1.16.2

@seankhliao seankhliao changed the title incorrect mime-type for .js files on windows 10 (text/plain instead of application/javascript) mime: incorrect mime-type for .js files on windows 10 (text/plain instead of application/javascript) Jun 18, 2021
@seankhliao
Copy link
Member

cc @neild for decision, though i believe this is working as intended

@sidecut
Copy link

sidecut commented Jun 22, 2021

cc @neild for decision, though i believe this is working as intended

Unfortunately, the docs contain this sentence: "On Windows, MIME types are extracted from the registry." This means that Microsoft can and did break the behavior of TypeByExtension. (Maybe we need a function called TypeByExtensionButIgnoringMicrosoftInsanity. ;) )

One could make the argument that the requirement for TypeByExtension is to return expected mime types, not merely types subject to Microsoft's breakage. In fact, MDN states explicitly this:

Per the HTML specification, JavaScript files should always be served using the MIME type text/javascript. No other values are considered valid, and using any of those may result in scripts that do not load or run.

Arguably, the current implementation is incorrect because it depends on an unreliable operating system feature. Adherence to the expectations of millions of developers and to industry standards should be the requirement. The requirement should not be to comply with an unreliable Windows feature.

Changing the function to ignore Microsoft's insanity would be a breaking change, but maybe a breaking change is better than a function whose implementation allows it to be broken by Microsoft. Therefore, for crucial file types -- html, css, and js -- perhaps the mime types should be hardcoded. Yes, a breaking change. But a breaking change that fixes and prevents breakage.

@dvaldivia
Copy link

also @mattn has a PR to disallow the override of this type by default with the option to do it if needed via an argument to setExtensionType

https://go-review.googlesource.com/c/go/+/191917/

@jahagirdar
Copy link

@tushardas ,
Did you solve the issue?
I am facing the same problem on linux env.
Loading module from “http://localhost:3000/polyfills.d103671dae517af0.js” was blocked because of a disallowed MIME type (“text/plain”).

Most of the answers here are for Window's OS, Should there be a separate ticket for Linux?

@parasit
Copy link

parasit commented Jan 13, 2022

Same problem in Windows 11. Go 1.17.5
Simple app:

	fs := http.FileServer(http.Dir("./static"))
	router.PathPrefix("/static/").Handler(http.StripPrefix("/static/", fs))
        log.Fatal(http.ListenAndServe(":8080", router))

In the static folder are some js/vue files, but all .vue files are served as 'text/plain' despite the fact that the content type is set correctly in the registry.

reg query "HKCR\.vue\Content Type"

HKEY_CLASSES_ROOT\.vue\Content Type
    (Default)    REG_SZ    application/javascript

@Khazbs
Copy link

Khazbs commented Jan 24, 2022

Windows is just being Windows, wasted half an hour figuring out why JS was served as text/plain

@SinguJ
Copy link

SinguJ commented May 17, 2022

I had the same problem and I borrowed dvaldivia solution.
If you don't want to change the Windows registry, you can modify it like this in code:

// Execute before the service runs.
func init () {
    _ = mime.AddExtensionType(".js", "text/javascript")
}

@gopherbot
Copy link

Change https://go.dev/cl/406894 mentions this issue: mime: ignore .js => text/plain in Windows registry

@ianlancetaylor
Copy link
Contributor

This situation is clearly unfortunate but I don't think that changing the mime package is the right approach. In general local system configuration should override defaults, not the other way around. I don't know why Windows is providing a strange configuration, but overriding the local configuration is just going to produce a different set of strange bugs.

The problem is not unique to Go; here is the same problem reported for Python: https://bugs.python.org/issue43975 , https://www.taricorp.net/2020/windows-mime-pitfalls/ .

This bug report says that it is a problem with Visual Studio: https://developercommunity.visualstudio.com/t/installer-mime-type-for-js-extension-is-set-to-tex/954263 .

If we do something here it should be a very focused fix on this specific problem. I suggest https://go.dev/cl/406894. Can somebody who is encountering this problem on their Windows system please see if that patch fixes it? Thanks.

@dmitshur dmitshur added this to the Go1.19 milestone May 30, 2022
@dmitshur dmitshur added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels May 30, 2022
@golang golang locked and limited conversation to collaborators May 30, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done. OS-Windows
Projects
None yet
Development

Successfully merging a pull request may close this issue.