Express.js,意外令牌 <

IT技术 javascript node.js express reactjs react-router
2021-05-11 16:23:54

我有一个简单的快速服务器,看起来像这样:

快速应用:

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);
});

和简单的html 文件:

<!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>

在 bundle.js 中,我有带有客户端路由的 ReactJS 应用程序:

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'));

每当我尝试导航到域:端口/(路由器支持此路由)时,一切都很好。但是,当我尝试导航到更复杂的 URL 时,例如domain:port///..等,我在浏览器中遇到错误:

bundle.js:1 Uncaught SyntaxError: Unexpected token <

看起来像从静态服务器响应发送 bundle.js 而不是使用 index.html 和 bundle.js 内部有 html 标记。

我怎样才能解决这个问题?

谢谢!

4个回答

似乎发生了环回,因为*规则index.html每次都在服务,当bundle.js找不到时,它将index.html改为服务,从而尝试解析<为 javascript。

如果你愿意的话,有点像索引

步骤1

文件夹结构:

public

   -> index.html

   -> bundle.js

第2步

像这样配置静态路径

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

第 3 步

确保它配置正确。转到浏览器并直接访问您的 js 文件,例如

localhost:3000/bundle.js

如果您看到您的 javascript ...万岁。如果不是,则与第 2 步战斗,然后检查第 3 步

步骤4

在 ui 中的脚本标记中使用相同的路径,例如

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

我通过添加以下行解决了同样的问题:

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

DOT 从 在 index.html 中,子路由将起作用!因为 express 总是会找到带有 * catch all 路由的包

我的修复在。我的回购,检查出来:https : //github.com/nickjohngray/staticbackeditor

要了解为什么以及如何执行此操作,请继续阅读:

解决方法是在输出脚本标记时告诉 webpack 告诉它使包的路径成为绝对路径(而不是相对路径),以便在 webpack.config 中设置 publicPath '/'(根)和文件名 'bundle.js' ,然后 HtmlWepackPlugin 将嵌入脚本标记,如

<script src="/bundle.js">

这就是我们想要的!

不是

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

这是我的 webpack.config 的一个片段,以允许子路由

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

如果路径是相对的,这里是一个流程示例:像

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

那错了!杀死“ .

环境

后端是 express 服务器,bundle.js 和 index.html 文件位于 public static dist 文件夹中

Express 有一个使用 * 为 index.html 文件提供服务的所有请求的捕获所有路由,例如

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

Index.html 文件有这个脚本标签(注意使这个路径相对的 . )

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

脚步

  • 用户请求页面/编辑路由

  • Express 返回 index.html 文件

  • Web 浏览器读取此文件

  • 浏览器找到脚本标签

  • 浏览器请求获取路径为 ./bundle.js 的脚本

  • Express 在静态文件夹中查找此文件

  • 它没有找到,

  • 所以它再次返回 index.html 作为 catch all 路由被触发

  • 并且 BANG 网络浏览器出现错误。

所以服务器返回的是 index.html 而不是 bundle.js 出现这种情况是因为 catch all 路由运行了 sine express 没有找到 bundle.js 在文件夹编辑中。

现在就对流如果我们将 html 文件脚本的源代码更改为绝对路径,那么无论用户在什么路径上,express 都会找到它

  • 用户请求页面/编辑路由
  • Express 返回 index.html 文件
  • Web 浏览器读取此文件
  • 浏览器找到脚本标签
  • 浏览器请求获取路径为 /bundle.js 的脚本
  • (注意上面的 . 不见了!)
  • Express 在静态文件夹中查找此文件
  • 它找到了,
  • 所以它返回 bundle.js 和 BANG!子路线工作!