2

Hi I'm new to web development. I have three files, index.html, myscript.js and server.js. A button on index.html calls the messageServer function in myscript.js which sends an XMLHttpRequest to server.js running Express on Node. The server receives the request but the response in myscript.js is always null. The readyState goes 1 and then 4. Why is it null? Thanks in advance
Edit: the response status code is 0
index.html:

<!DOCTYPE html>
<html>
    <head>
        <title id="title">Page Title</title>
        <script src="myscript.js"></script>
    </head>
    <body>
        <h1 id="header">Header</h1>
        <form>
            <input type="button" value="Message Server" onclick="messageServer();">
        </form>
    </body>
</html>

myscript.js

function messageServer() {
    const xhr = new XMLHttpRequest();
    const url = 'http://localhost:8888/';

    xhr.responseType = 'json';
    xhr.onreadystatechange = () => {

        log("Ready state: " + xhr.readyState + ", response: " + xhr.response);

        if(xhr.readyState === XMLHttpRequest.DONE) {
            return xhr.response;
        }
    };

    xhr.open('GET', url);
    xhr.send();
}

and server.js

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

const port = 8888;

let requestCount = 1;

app.get('/', (req, res, next) => {
    console.log('Received get request ' + requestCount);
    ++requestCount;
    res.send(JSON.stringify({myKey: 'myValue'}));
});

app.listen(port);
Ben Lamb
  • 47
  • 2
  • 7

1 Answers1

1

main problem is CORS (cross origin resource sharing) is not enabled on express, chrome is bit strict about CORS.

put below code before app.get to enable cross-origin resource sharing

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

complete server.js should be as below

var express = require("express");
var app = express();

const port = 8888;
let requestCount = 1;

app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
  });

app.get('/', (req, res, next) => {
    console.log('Received get request ' + requestCount);
    ++requestCount;
    res.send(JSON.stringify({myKey: 'myValue'}));
});

app.listen(port);

Then check on network tab of developer tool, you should see {"myKey":"myValue"} in response.

Rajnikant
  • 2,176
  • 24
  • 23
  • Yes! That's it, thank you. Just a quick question: is this normal to have to add this to node apps? Is it because I'm running it locally or what – Ben Lamb Jun 09 '18 at 22:15
  • it is not just applicable to node apps, in your example it is because of XmlHttpRequest, here is full link https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS , and What requests use CORS? section should explain it. even in my answer I put "*" it should be your domain/* so for your example http://localhost:8888/* . – Rajnikant Jun 09 '18 at 23:15