首页 > 解决方案 > 如何为带有 JS 和 NodeJS 服务器的标准 html 页面正确配置 app.yaml?

问题描述

我正在 AppEngine 上设置一个简单的网络应用程序,但在配置 app.yaml 时遇到了一些问题。它包括一个 HTML 页面、一个 JS 脚本和一个 NodeJS 服务器。

我的项目结构:

\app.yaml
\package.json
\www
    \index.html
    \js
        \server.js
        \index.js

索引.html:

<!DOCTYPE html>
<html>
<body>
    <div id="JShere" >Hello World !</div>
    <div id="ReqAnswer"></div>
</body>
<script src="js/index"></script>
</html>

index.js:

  document.getElementById('JShere').innerHTML = "JS is running";
  var xhr = new XMLHttpRequest();
  xhr.open('GET', "/srv", true);
  xhr.send();
  xhr.addEventListener("readystatechange", processRequest, false);

  function processRequest(e) {
    if (xhr.readyState == 4 && xhr.status == 200) {
        document.getElementById('ReqAnswer').innerHTML = xhr.responseText;
    }
}

node.js 服务器:

const express = require('express');
const app = express();

app.get('/srv', function (req, res) {
  res.send('Request anwser')
})

const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}...`);
});

包.json:

...
  "scripts": {
    "start": "node www/js/server.js",
    "test": "mocha --exit test/*.test.js"
  },
...

应用程序.yaml:

runtime: nodejs10

handlers:

- url: /
  static_files: www/index.html
  upload: www/index.html

- url: /index
  static_files: www/index.html
  upload: www/index.html

- url: /page2
  static_files: www/page2.html
  upload: www/page2.html

- url: /www
  static_dir: www

当我在本地检查时,index.js正确修改了index.html,但是当我将它部署到 App Engine 时,index.js被阻止(MIME 类型(« text/html »))。然后它“无法在index.html上加载” 。虽然,该脚本仍然向服务器发起 GET 请求并收到 404 错误。是 App.yaml 问题还是其他问题?

标签: javascripthtmlnode.jsgoogle-app-engineapp.yaml

解决方案


仔细检查 GAE 日志条目以获取所请求的确切 URL(并以 404 拒绝)。url这就是您的静态处理程序模式之一通常需要匹配的内容。如果发生匹配,则应该发生由相应处理程序的static_file/static_dirupload规范(相对于您的应用程序的顶级目录 - app.yaml 文件所在的位置)指定的文件。

假设初始请求是针对/. 这与您的第一个静态处理程序相匹配,因此您www/index.html将得到服务。

但是index.html文件引用了js/index里面的脚本,所以另一个请求将跟随该 URL。但是该 URL 与您的任何处理程序的模式都不匹配,因此它会得到 404。您也没有任何名为 just 的文件index

假设在这种情况下您想要提供的实际上是www/js/index.js您必须提供的文件:

  • 更正文件中的index.html文件名引用:

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

  • 确保此引用与静态处理程序url模式匹配。可能是这样的(对于每个以结尾的请求路径,.js都将尝试提供与该路径匹配但相对于www/js目录的文件):

    - url: /(.*\.js)$
      static_files: www/js/\1
      upload: www/js/.*\.js$
    

或者,您可以使用可应用于多种类型文件的方案,而不是那些以 结尾的文件.js

  • www使用文件中的前缀引用index.html文件:

    `<script src="www/js/index.js"></script>`        
    
  • 重新使用您的最后一个处理程序,但在其上添加一个通配符以url确保匹配下的所有内容www(因为www/blah不会匹配 justwww模式):

    `- url: /www/*`
    

也可以在没有.js后缀的情况下引用脚本,但是您需要专门针对该文件的处理程序 - 将其映射到实际文件名,您不能使用通配符。所以我不推荐这个,因为它很快就会变得非常复杂。

您必须同样考虑您需要提供的所有其他静态元素。


推荐阅读