How to send from localhost to localhost and present result on the page?

Hi everyone!

So, I’ve completed the first backend project (create a timestamp microservice, here), and I’ve had this crazy thought of creating a small UI on the front-end to
(1) Let the user type in their API call (or they could just do it via the browser address).
(2) Have an element on the page that receives the result of the API call, and display it on the page (instead of the “sample output” section).

In order to do that, do I have to run two separate localhosts? (one for the server (my microservice), and one for the client, the browser that sends the requests?

My issue is - I’m not sure how to make a request to the service, exactly. In the past, when doing front-end projects, I used async/ await with the “fetch” command (and then display the result on a page element). Here, however, it’s causing issues:

Is there another way to do this? Am I missing something?

Thanks!

1 Like

OK, reading the Firefox error message a bit more carefully, I can see an error:

Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.
    result http://127.0.0.1:5500/timestamp-microservice/src/app.js:8
    <anonymous> http://127.0.0.1:5500/timestamp-microservice/src/app.js:12
app.js:8:23
    result http://127.0.0.1:5500/timestamp-microservice/src/app.js:9
    AsyncFunctionThrow self-hosted:811
    (Async: async)
    <anonymous> http://127.0.0.1:5500/timestamp-microservice/src/app.js:12

If I understand correctly, it means that the client (browser) is trying to send a request to itself, and it doesn’t like that, apparently. It also shows that the port is 5500, which is the LIveServer port, though my timestamp service port is 5432.

So, does this mean that the localhost is trying to send a request on 5500 while listening to requests on 5432, and it somehow can’t do? Can localhost only do one thing at a time? Or can it act as the client and server at the same time?

Thanks for clarifying!

Your fetch end point PORT is 5432 is that running a server as well or is it only on 5500? Are you sure that server is actually runnning?

Also I presume that res.json() doesn’t need to be awaited, but you may double check.

I tried to emulate the error and found a few things.

The main concept here is CORS. I don’t know much but this is my take.

There are broadly 2 types of requests you can make:

  1. Same Origin: same domain name + port. An example here StackOverFlow
  2. Cross Origin: To a different domain or port i.e needs CORS protocol.

So now you can start classifying your requests. The requests to different schemen, domains, or ports (i.e cross origin) won’t succeed the server accepts CORS. Fortunately, if you are under control of the server, this is extremely easy. See express example.. It can be also done manually by setting the appropriate headers.

Next paragrapg was wrong (thanks @lasjorg ):

A simpler solution is to just use fetch(url, {mode:"no-cors"}) then your request is actually a valid no-cors request."

PD: to learn more about CORS you can build some websites that gets data from the API-list on github..

Mind that many (for example the dogs APIs) aren’t working anymore.

Where is the client code located? You can put it inside the public folder that express.js is serving the static files from and reference it like the CSS file.

Create a button in the HTML that will do the fetch when clicked so you are sure the API is up and running before the client makes the request. Then in the client code just fetch against the /api routes without specifying the host or port.

const btn = document.querySelector('#fetch');

btn.addEventListener('click', () => {
  fetch('/api/timestamp')
    .then((res) => res.json())
    .then((data) => console.log(data));
});

@equinox Using no-cors is not an option. It will return an opaque response that you can’t use for much of anything.

https://fetch.spec.whatwg.org/#concept-filtered-response-opaque

1 Like

Hey brother, thanks for taking the time. Yes, the “server” itself is running and listening on port 5432 (checked it in the console).

Re res.json(), it usually is awaited, yes. This is because (as I understand it - correct me if I’m wrong), the previous line returns a promise (so res is a promise), and I then I want to json-ify it before I do something with the data I received. If I wanted to console.log the data that’s in the res (ie, the promise), I want to make sure that it’s been json-ify before I do anything with it.

Hey friend, thanks for taking the time.

The client code is in a “src” folder and included in the index.html file header (as if it were a stylsheet). I can put it in the public folder as you suggest, though I’m not sure what the difference would be.

Re the button and the code - yes, that’s my intention actually. Why don’t do I need to specify “localhost” in the fetch request? Is it implied somehow?

@equinox thanks friend but I must admit I’m lost with the CORS. Might it be overkill here?

I think you could just do this steps (if your server is express):

  1. npm i cors
  2. Add the line app.use(cors()) after app is defined
  3. Restart servers.

Now the server accepts requests from cross-origins. @idanlib