最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Express.js, Unexpected token < - Stack Overflow

programmeradmin0浏览0评论

I have simple express server which looks like that:

Epxress application:

var express = require('express');
var compression = require('compression');
var path = require('path');
var cors = require('cors');
var router = express.Router();

var app = express();

app.use('/bundle', express.static(path.join(__dirname, '/bundle')));

app.enable('trust proxy');

app.use(compression());

app.get('*', function(req, res) {
    res.header('Cache-Control', "max-age=60, must-revalidate, private");
    res.sendFile( path.join(__dirname, 'index.html') );
});


var server = app.listen(process.env.PORT || 5000, function () {
    var host = server.address().address;
    var port = server.address().port;
    console.log(`Example app listening at http://%s:%s`, host, port);
});

And simple html file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>React Router test</title>
</head>
<body>
    <div id="root"></div>
    <script src="bundle.js"></script>
</body>
</html>

Inside of bundle.js i have ReactJS application with client-side routing:

render((
    <Router history={browserHistory}>
        <Route path="/" component={App}>
            <Route path="about" component={About} />
            <Route path="about2" component={About2} />
            <Route path="about3" component={About3} />
            <Route path="*" component={NoMatch} />
        </Route>
        <Route path="*" component={NoMatch} />
    </Router>
), document.getElementById('root'));

Whenever i try to navigate to domain:port/ (this route is supported by router) everething is OK. But when i try to navigate to more complex URL, like domain:port///.. etc i got an error in browser:

bundle.js:1 Uncaught SyntaxError: Unexpected token <

looke like instead of send bundle.js from static server response with index.html and inside bundle.js there is html markup.

How can i fix this?

Thanks!

I have simple express server which looks like that:

Epxress application:

var express = require('express');
var compression = require('compression');
var path = require('path');
var cors = require('cors');
var router = express.Router();

var app = express();

app.use('/bundle', express.static(path.join(__dirname, '/bundle')));

app.enable('trust proxy');

app.use(compression());

app.get('*', function(req, res) {
    res.header('Cache-Control', "max-age=60, must-revalidate, private");
    res.sendFile( path.join(__dirname, 'index.html') );
});


var server = app.listen(process.env.PORT || 5000, function () {
    var host = server.address().address;
    var port = server.address().port;
    console.log(`Example app listening at http://%s:%s`, host, port);
});

And simple html file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>React Router test</title>
</head>
<body>
    <div id="root"></div>
    <script src="bundle.js"></script>
</body>
</html>

Inside of bundle.js i have ReactJS application with client-side routing:

render((
    <Router history={browserHistory}>
        <Route path="/" component={App}>
            <Route path="about" component={About} />
            <Route path="about2" component={About2} />
            <Route path="about3" component={About3} />
            <Route path="*" component={NoMatch} />
        </Route>
        <Route path="*" component={NoMatch} />
    </Router>
), document.getElementById('root'));

Whenever i try to navigate to domain:port/ (this route is supported by router) everething is OK. But when i try to navigate to more complex URL, like domain:port///.. etc i got an error in browser:

bundle.js:1 Uncaught SyntaxError: Unexpected token <

looke like instead of send bundle.js from static server response with index.html and inside bundle.js there is html markup.

How can i fix this?

Thanks!

Share Improve this question asked Aug 3, 2016 at 12:09 Yafim DziukoYafim Dziuko 831 gold badge2 silver badges8 bronze badges 3
  • 1 try <script src="/bundle.js"></script> – Kokovin Vladislav Commented Aug 3, 2016 at 12:38
  • @Utro works for me. thanks! – Yafim Dziuko Commented Aug 3, 2016 at 13:13
  • @KokovinVladislav thanks, it works in my case – Sherali Turdiyev Commented May 18, 2017 at 8:28
Add a comment  | 

4 Answers 4

Reset to default 13

There seems to be a loopback occuring, since the * rule is serving a index.html every time, and when bundle.js is not found, it will serve index.html instead, thus trying to parse < as javascript.

A sort of index-ception if you will...

Step 1

Folder structure:

public

   -> index.html

   -> bundle.js

Step 2

Configure static path like this

app.use(express.static('public'))

Step 3

Ensure if it is properly configured .Go to browser and access your js file directly like

localhost:3000/bundle.js

If you see your javascript ...Hurrray. If not then fight with step 2 then check step 3

Step 4

use same path in script tag in ui like

<script src="/bundle.js" type="text/javascript"></script>

I fixed the same issue by adding the following line:

app.use(express.static(path.join(__dirname, "public")));

Put simply remove the DOT from in index.html and the sub routes will work! As express will always find the bundle with a * catch all route

My fix is in. my repo, check it out: https://github.com/nickjohngray/staticbackeditor

To Understand why and how to do this read on:

The fix is to tell webpack when it outputs the script tag to tell it to make the path to the bundle absolute (not relative ) to do this in webpack.config set the publicPath '/' ( root) and filename 'bundle.js' , then the HtmlWepackPlugin will embed the script tag like

<script src="/bundle.js">

and that's what we want!

NOT the

<script src="./bundle.js">

Here is a snippet of my webpack.config to allow sub routes

 entry: ['babel-polyfill', './src/client/index.tsx'],
    output: {
       path: path.join(__dirname, outputDirectory),
       filename: 'staticbackeditor.js',
       publicPath: '/'
    }

Here an example of the flow if the path is relative: like

<script src="./bundle.js">  

that's wrong! Kill the "."

Environment

Backend is express server and the bundle.js and index.html files are in the public static dist folder

Express has a catch all route for all requests using * that serves the index.html file like

app.use('*', (req, res) => {
   res.sendFile(path.resolve('dist', 'index.html'))
})

Index.html file has this script tag ( notice the . that makes this path relative )

<script src="./bundle.js"></script>

Steps

  • User requests pages/edit route

  • Express gives back index.html file

  • Web browser reads this file

  • Browser finds the script tag

  • Browser makes request to get the script with the path ./bundle.js

  • Express looks for this file in the static folder

  • It does not find it ,

  • so it returns index.html again as the catch all route is triggered

  • And BANG web browser gives error.

So the server returned index.html instead of bundle.js This occurred because the catch all route was run sine express did not find bundle.js In the folder edit.

Right Flow Now! If we change the html file script’s source to an absolute path so express will find it no matter what path the user is on

  • User requests pages/edit route
  • Express gives back index.html file
  • Web browser reads this file
  • Browser finds the script tag
  • Browser makes request to get the script with the path /bundle.js
  • ( notice above the . is gone! )
  • Express looks for this file in the static folder
  • It finds it ,
  • so it returns bundle.js And BANG! The sub routes work!
发布评论

评论列表(0)

  1. 暂无评论