Kian Soltani
Kian Soltani

Reputation: 97

How to correctly configure app.yaml for a standard html page with JS and NodeJS server?

I'm setting up a simple web app on AppEngine and have some trouble with configuring the app.yaml. It includes a HTML page, a JS script and a NodeJS server.

My project structure:

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

index.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 server:

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

package.json:

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

app.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

When I check locally, index.js modify index.html correctly but when I deploy it to App Engine, index.js is blocked (MIME type (« text/html »)). it then "fails to load the " on the index.html. Although, the script still launch the GET request to the server and get a 404 error. Is it an App.yaml problem or something else is wrong?

Upvotes: 2

Views: 1330

Answers (1)

Dan Cornilescu
Dan Cornilescu

Reputation: 39824

Check closely the GAE log entries for the exact URL being requested (and rejected with 404). That's what would normally need to be matched by one of your static handlers' url pattern. If a match occurs then the file specified by the respective handler's static_file/static_dir and upload specs (which are relative to your app's top dir - where the app.yaml file exists) should happen.

Let's assume the initial request is for /. That's matched by your 1st static handler, so your www/index.html will be served.

But the index.html file references the js/index script inside, so another request will follow with that URL. But that URL doesn't match any of your handlers' pattern, so it'll get a 404. You also don't have any file named just index.

Assuming what you'd like to serve in this case is actually the www/js/index.js file you'd have to:

  • correct the filename reference in your index.html file:

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

  • make sure this reference is matched by a static handler url pattern. Something like this maybe (which for every request path ending with .js will attempt to serve a file matching that path but relative to the www/js directory):

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

Alternatively you could use a scheme that can be applied to multiple type of files, not that those ending in .js:

  • reference the file using the www prefix in your index.html file:

    `<script src="www/js/index.js"></script>`        
    
  • re-use your last handler, but adding a wildcard to its url to ensure matches for everything under www (as www/blah won't match the just www pattern):

    `- url: /www/*`
    

It's also possible to reference the script without the .js suffix, but then you'd need a handler specifically for that file - to map it to the actual filename, you can't use wildcards. So I wouldn't recommend this as it can get pretty complex very quickly.

You'd have to similarly consider all the other static elements you need to serve.

Upvotes: 2

Related Questions