简体   繁体   中英

Expressjs GET request on javascript files as text/html

I have an application mostly in Angular, and I want to hook it up to Express to encrypt and send private API keys so they won't be stored plainly on the client.

My problem is that the browser reads statically served js files as text/html, which is causing my javascript to not load. You can see that the response is 200 and the file is there, just not being interpreted correctly.
IMG

index.html has many script requests like these

<script type="text/javascript" src="/keys.js"></script>
<script type="text/javascript" src="/public/lib/underscore/underscore-min.js"></script>
<script type="text/javascript" src="/public/lib/jquery/dist/jquery.min.js"></script>
<script type="text/javascript"  src="/public/lib/bootstrap/dist/js/bootstrap.min.js"></script>
...

Express routing code:

var express = require('express');
var path = require('path');

var app = express();

app.use(express.static(path.resolve('./public')));

app.get('*', function(req,res) {
    res.sendFile(path.resolve('./public/views/index.html'));
});

app.listen(3000);

Anyone experienced with express - what is the proper way to serve static files with different MIME types? I eventually need to serve text/css types as well.

You've configured your application to return index.html for every request:

app.get('*', function(req,res) {
    res.sendFile(path.resolve('./public/views/index.html'));
});

So express dutifully does just that, serves index.html for any and all requests, including the requests that you want to have return the js files via your script tags. For example, a request to /public/lib/underscore/underscore-min.js will actually return the file at /public/views/index.html .

A simple fix would be to just return index.html for a root request:

app.get('/', function(req,res) {
    res.sendFile(path.resolve('./public/views/index.html'));
});

In this way your index.html would be served at the root but your javascript assets could still be reached because you aren't serving index.html for every request.

Additionally, since you've told express that static assets can be found at /public , there's no need to include that directory when requesting them. So, your script includes should look like:

<script type="text/javascript" src="/lib/underscore/underscore-min.js"></script>
<script type="text/javascript" src="/lib/jquery/dist/jquery.min.js"></script>
<script type="text/javascript"  src="/lib/bootstrap/dist/js/bootstrap.min.js"></script>

I think this is your problem:

app.get('*', function(req,res) {
    res.sendFile(path.resolve('./public/views/index.html'));
});

You're sending index.html for literally every request.

The actual problem is not that app.get('*', ...) resolves for all requests (and overwrites responses from other middlewares), but that express-static is used incorrectly here.

In your example express-static does not resolve the request to a valid static-file in that directory and just invokes the next middleware / handler, which is in your case the app.get('*', ...). And that's why you see your index.html for every request.

Solutions

- <script type="text/javascript" src="/public/lib/underscore/underscore-min.js"></script>
+ <script type="text/javascript" src="/lib/underscore/underscore-min.js"></script>

Either you specify your resources in the HTML without the prefix /public ,

- app.use(express.static(path.resolve('./public')));
+ app.use('/public', express.static(path.resolve('./public')));

Or you adjust your express routing to handle the path prefix.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM