Search code examples
javascriptjsonfetch-apihttp-status-code-405

Send form to local server with fetch() POST failed. Error 405


I would like to send a filled out form in JSON format via fetch POST to a local server, which has been set up with "npm http-server". The server has been started with the command "http-server --cors". Error message when clicking on the submit button is: "405 (Method Not Allowed)". I tried it in Chrome and Edge.

I am a bit overwhelmed now. Is it related to the CORS security settings? Do I need a server side node.js script to allow this call? Is it because I only use a local server? I'm lost...

Any help is highly appreciated! Very new to all this but I am eager to learn.

Below is the JSON and the JavaScript code. Both are in the same main directory on the local server:

JSON:

    [
  {
    "id":1,
    "name":"Rick",
    "email":"rick@gmail.com"
  },
  {
    "id":2,
    "name":"Glenn",
    "email":"glenn@gmail.com"
  },
  {
    "id":3,
    "name":"Negan",
    "email":"negan@gmail.com"
  }
]

HTML file to show the JSON and upload a new entry:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Fetch API Sandbox</title>
</head>

<body>
  <h1>Fetch API Sandbox</h1>
  <button id="getUsers">Get JSON</button>

  <div id="output"></div>
  <!--Hier wird das JSON reingeschrieben-->

  <form id="addPost">
    <div> <input type="text" id="id" placeholder="ID"> </div>
    <div> <input type="text" id="name" placeholder="Name"> </div>
    <div> <input type="text" id="email" placeholder="E-Mail"> </div>
    <input type="submit" value="Submit">
  </form>

  <script>
    document.getElementById('getUsers').addEventListener('click', getUsers);
    document.getElementById('addPost').addEventListener('submit', addPost);

    function getUsers() {
      fetch('users.json')
        .then(function(response) {
          if (response.ok)
            return response.json();
          else
            throw new Error("Names could not be loaded!")
        })
        .then(function(json) {
          console.log(json);
          let output = '<h2>Users</h2>';
          json.forEach(function(user) {
            output += `
				<ul>
				  <li>ID: ${user.id}</li>
				  <li>Name: ${user.name}</li>
				  <li>Email: ${user.email}</li>
				</ul>
			  `;
            console.log(output);
            document.getElementById("output").innerHTML = output;
          });
        })
    }

    function addPost(e) {
      e.preventDefault();

      let id = document.getElementById('id').value;
      //console.log(id);
      let name = document.getElementById('name').value;
      let email = document.getElementById('email').value;

      fetch('users.json', {
          method: 'POST',
          mode: 'cors',
          headers: {
            'Accept': 'application/json, text/plain, */*',
            'Content-type': 'application/json',
            'Access-Control-Allow-Origin': '*'
          },
          body: JSON.stringify({
            id: id,
            name: name,
            email: email
          })
        })
        .then((res) => res.json())
        .then((data) => console.log(data))
    }
  </script>

</body>

</html>


Solution

  • http-server is a static files server. It will only handle GET requests.

    However, you are in luck, because there is a similar package, which allows you to run a RESTful API with a single command. It's called json-server. You only need to provide a JSON file which will take the role of your "database". In your case the JSON can look like this:

    {
      "users": [
        {
          "id": 1,
          "name": "Rick",
          "email": "rick@gmail.com"
        },
        {
          "id": 2,
          "name": "Glenn",
          "email": "glenn@gmail.com"
        },
        {
          "id": 3,
          "name": "Negan",
          "email": "negan@gmail.com"
        }
      ]
    }
    

    When you run the server with json-server db.json this will create GET/POST/PATCH/DELETE method handlers for the endpoint /users. You will then be able to get/insert/alter/delete records from the "database". In your case, the fetch call endpoint URL has to be changed to: fetch('localhost:3000/users', ...).

    You can install the package globally by running npm install -g json-server.