Because both ways are used. Microsoft relies on file names, linux on the first bytes of the file.
Not quite correct. For html, that is to signal standard compliance, you can leave it away and the browser will still handle it. For the bash one, all (most) shell scripts use .sh, so you need to give a shebang to tell the loader which executable (sh, bash, zsh, csh, …) to use
Also on Linux xdg does take file extensions into account, just executables do not