47

I have a project in which the user interface is based on angular 8 and the backend is a springboot java service. The entire project is a multi module project with the angular part being a separate module with front-end builder being used to build the angular code into a single executable jar. The application runs fine when the embedded tomcat is used. I have a new requirement to try and deploy the angular ui part separately on an external tomcat . But when i copy the dist folder to the webapps folder and try to serve it , the browser blocks the request saying :

Loading module from “http://localhost:8080/polyfills-es2015.js” was blocked because of a disallowed MIME type (“text/html”).

browser screenshot

After doing some google search I came to understand that the issue occurs because angular 8 cli fails to add the type attribute to the script tag in index.html . When i manually add the type,everything works fine. Can anyone please help me to understand why this is happening, and also a possible fix for the issue other than manual editing.

Generated index.html :

<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>My Application</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <i class="fas fa-chart-area"></i>
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>

<body style="margin: 0;">
  <app-root></app-root>
<script src="runtime-es2015.js" type="module"></script><script src="runtime-es5.js" nomodule defer></script><script src="polyfills-es5.js" nomodule defer></script><script src="polyfills-es2015.js" type="module"></script><script src="styles-es2015.js" type="module"></script><script src="styles-es5.js" nomodule defer></script><script src="scripts.js" defer></script><script src="vendor-es2015.js" type="module"></script><script src="vendor-es5.js" nomodule defer></script><script src="main-es2015.js" type="module"></script><script src="main-es5.js" nomodule defer></script></body>

</html>

So, to summarize everything that works , it's as follows :

  • The type attribute is no longer mandatory in HTML5, hence angular cli no longer adds it as an attribute. In embedded tomcat , the assets were being copied to the ROOT which works perfectly as , when I deployed in external tomcat ,I kept the assets under a folder in webapps which meant I had to amend the baseHref field (either during build using command or after build manually) to reflect the same. The following works :
  • Keeping the assets under ROOT folder in webapps (everything works perfectly because the js files are now under the root / ).
  • Keeping the files under a folder say for instance MyApp and specifying that as baseHref in index.html .

Related link

Ananthapadmanabhan
  • 5,706
  • 6
  • 22
  • 39
  • 2
    Seems like the server thinks the JS file is a HTML file... – dan1st Jan 27 '20 at 06:09
  • 2
    I encountered this b/c my browser was trying to get a non-existent js file due to some cache issue. A simple CTRL+SHIFT+R fixed it. – Stack Underflow May 26 '21 at 21:20
  • Did you ever find the answer to this? I am seeing the same issue after upgrading from angular 7 to angular 8. – Andrew Jul 15 '21 at 15:51
  • @Andrew The issue that I faced got resolved with the accepted answer, a summary of which I have added to the question itself. – Ananthapadmanabhan Jul 16 '21 at 04:51
  • I upvoted "Stack Underflow" because his/her comment about "non-existent js file" pointed me in the right direction. I was running into a similar problem caused by a misnamed js file. The main takeaway for me is that you will get this confusing mime type error if the file is not found. – PeteH Jan 18 '22 at 22:42

7 Answers7

53
 <base href="/">

is the issue , change it to your context root . Or change it to

<base href=".">

Browser is unable to find your JS file because it looks for JS file relative to base href.

Your base href= "/" , so it looks for all js file in the in "localhost:8080/", but your JS files might have present in "localhost:8080/someRoot"

One more solution you can think of is, deploying in the ROOT folder of tomcat with out context root , if that is allowed for your project

aravind
  • 978
  • 3
  • 12
  • 21
  • 1
    Then why does it work when i add the type="text/javascript" to the index.html script tags ? Also, I have no issue in serving this from an embedded tomcat . – Ananthapadmanabhan Jan 27 '20 at 06:08
  • 1
    Do you have Js file in this location ? "http://localhost:8080/polyfills-es2015.js" that means do you have js directly in your webapps folder ? – aravind Jan 27 '20 at 06:14
  • Embedded tomcat might have deployed the project in ROOT folder. Please note that type="text/javascript" is optional in HTML5, your code should work event if it doesn't have "text/javascript" – aravind Jan 27 '20 at 06:31
  • I have added it to the ROOT of tomcat. – Ananthapadmanabhan Jan 27 '20 at 06:33
  • But it was not working when it was being served from another folder. I think you are right , keeping it in ROOT works. – Ananthapadmanabhan Jan 27 '20 at 06:34
  • This also happens with Angular 11, using ng serve on a non-root path – gbronner Mar 03 '21 at 20:50
  • already have the same problem even if is well set , what workaround possible to that ? – firasKoubaa Apr 22 '21 at 23:04
  • @firasKoubaa in my case it was due to my module was in a relative path and I didn't add the '.js' to the file. So it worked with '../../my_dir/my_module.js' – josemfc May 20 '21 at 09:14
45

I had this issue trouble me for a while. For those of you like me who weren't careful, make sure you have the .js at the end of the file name in the import.

Kochez
  • 673
  • 4
  • 10
  • 1
    So for `dotenv`, I do this: `import dotenv from "./node_modules/dotenv"`. Isn't that correct? `import dotenv from "./node_modules/dotenv.js"` doesn't exist – puncher Jul 02 '22 at 19:31
12

The server thinks that your JS file is a HTML file.

This may be because the server-side recognition is buggy or the JS file is non-existent (and the server does not send a 404 status code?) or there is no js in it.

Because of that, it sends the Content-Type text/html.

The browser sees the content type, thinks this is no css and does not allow it.

If you specify the type(client side) or change the type server-side, it should work.

dan1st
  • 12,568
  • 8
  • 34
  • 67
  • Yes i have tried manually adding the type in index.html at server side and it works as i have said in the question. But why is angular cli not adding it during ng build ? – Ananthapadmanabhan Jan 27 '20 at 06:29
  • 1
    It seems that there is a problem with the automatical recognition of the file – dan1st Jan 27 '20 at 06:52
  • 1
    That's it in my case. My IDE automatically omitted the `.js` file extension when I created the import statement. Adding `.js` to `import { thing } from './file.js';` did the trick. – Robin van Baalen Aug 14 '21 at 17:15
  • What do you mean by "specify the type(client side) or change the type server-side". – Joe Moore Aug 22 '22 at 13:41
  • @meropis The content-type could be changed client-side with `type="text/html"` or server-side by sending a different `Content-Type` header back in the response. – dan1st Aug 22 '22 at 14:21
2

This is a solution it worked for my vanilla JS project

Problem Desc: The browser is not able to find the files you want, thus sends you a 404 HTML page as response to your script request (waits for a js, but gets some html instead)

  1. the import must have type="module" ex: <script type="module" src="./main.js"></script>

  2. All the imports must finish whit .js ex: import characterData from "./modules/data.js";

  3. If still doesn't work, remove all th imports and write it again (helps more in VSCode)

  4. If somehow still breaks, keep the main.js in the root folder and add all the other to a new modules folder

8koi
  • 182
  • 1
  • 1
  • 10
1

A couple of things have helped me during my learning phase of Typescript ES6 to solve the above error:

  1. Add .js at the end of the import statement. For e.g.: import {testModule} from './Classes.js';
  2. In the index.html file, change the script type to "module" instead of "text/javascript".
  3. In tsconfig.json comment out "module": "commonjs" and replace it with "target": "ES6".
  4. Delete all the files from your JS output folder and recompile the typescript to generate those files again.
1

Another reason is that the Vite bundler (Rollup?) sets the script file as an absolute path "/assets/index123.js" instead of relative "./assets/index123.js" in the index.html file

Lithifus
  • 41
  • 4
0

Make sure you have the .js in your import statement.

For me, I relied on VS Code to autopopulate the import for my ./add.js file, for which it wrote:

import { add } from "./add";

And I saw the error in Firefox.

Loading module from “http://127.0.0.1:5500/add” was blocked because of a disallowed MIME type (“text/html”).

Once I added the .js to make it:

import { add } from "./add.js";

It worked.

user1160006
  • 533
  • 4
  • 12