javascriptjsongopostfibers

Fiber web framework can not send ajax request


Forgive me, but I do not know English well. I use the translator deepl.com. At this point Russian programmers could not help me. I am not a programmer, "I program only for myself". I have a problem - I can't send POST (JSON) request to server.

What I want to do - the server at Fiber which takes via POST request (JSON, XMLHttpRequest) 2 parameters from html page and after processing server gives me one string. I use Fiber because I once made a small static site for myself, and there in the "examples" was all clear. I did a quick ctrl+C - ctrl+V, just tweaked my code. Then I tweaked the html, js, css. And I have a working site! :-)

main.go - start the server (no problems here)

package main
 
import (
    "github.com/gofiber/fiber"
    "github.com/gofiber/fiber/middleware/logger"
)
 
func main() {
    app := fiber.New()
    app.Use(logger.New())
    app.Static("/", ".")
 
    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendFile("./main.html")
    })
 
    app.Post("/search", PostTodo)
 
    app.Listen(":3003")
 
}

search.go - logic on what to do after receiving the data. (so far just a kind of template, there is a small problem, but it mostly works).

package main
 
import (
    "fmt"
 
    "github.com/gofiber/fiber"
)
 
type Response_JSON struct {
    Name    string `json:"name"`
    Surname string `json:"surname"`
}
 
func PostTodo(c *fiber.Ctx) error {
    type request struct {
        Name    string `json:"name"`
        Surname string `json:"surname"`
    }
 
    var body request
 
    err := c.BodyParser(&body)
    if err != nil {
        return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
            "error": "Cannot parse JSON",
        })
    }
    fmt.Println("body: ", err)
 
    todo := Response_JSON{
        Name:    body.Name,
        Surname: body.Surname,
    }
 
    fmt.Println("todo: ", todo)
    my_request := "<div>" + todo.Name + "</div>"
    my_request = my_request + "<hr><div>" + todo.Surname + "</div>"
 
    return c.SendString(my_request)
}

main.html - home page

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Proba</title>
</head>
<body>
    <div class="container">
        <div class="logo">
            <h1>Proba</h1>        
        </div>        
        <form action="/search" class="search_form" method="POST">
            <div class="search">
                <input type="text" id="search_name" value="" name="search_name" placeholder="Search name...">
                <input type="text" id="search_surname" value="" name="search_surname" placeholder="Search surname...">
                <input type="submit" id="send" class="search_button" value="Go">
            </div>              
        </form>        
        <div id="result" class="result">
        </div>         
    </div>
    <script src="main.js"></script>
</body>
</html>

main.js - script processing forms after clicking (the main problem here)

let mybutton = document.getElementById("send");
 
mybutton.addEventListener("click", () => {
    let name = document.getElementById("search_name").value;
    let surname = document.getElementById("search_surname").value;
    let s = {};
    s.name = `${name}`;
    s.surname = `${surname}`;
    let search_json = JSON.stringify(s);
 
    console.log("s: ", s);
    console.log("name: ", name);
    console.log("surname: ", surname);
    console.log("search_json  ", search_json);    
 
    let request = new XMLHttpRequest();
    request.open('POST','/search');
    request.setRequestHeader('Content-type', 'application/json'); 
    request.onreadystatechange = function () {
        if (request.readyState == 4 && request.status == 200)
            document.getElementById("result").innerHTML=request.responseText;
        }
 
    request.send(search_json); 
});

main2.js - a trial js that works without "click" (through it I tried to understand where the problem is)

let user = {
    name: "Ivan",
    surname: "Ivanov"
};
console.log("user:", user);
 
 
let json = JSON.stringify(user);
console.log("json:", json);
let request = new XMLHttpRequest();
request.open("POST", "/search");
request.setRequestHeader('Content-type', 'application/json');
request.onreadystatechange = function () {
        if (request.readyState == 4 && request.status == 200)
            document.getElementById("result").innerHTML=request.responseText;
        }
request.send(json);

What I have: 1 - I start the server and go to the main.html. I fill in the data and click on the button (submit (Go)) and I see this result. The request is not sent and also strangely enough line console.log("s: ", s); did not work (output in the console did not happen). enter image description here

enter image description here

2 - However, if you use the script main2.js, which works immediately when the page loads, then everything seems to work. The data was sent and the server processed it and returned it to me. Although, for some reason in the file search.go output fmt.Println("body: ", err) - "nil", but in the variable "body" is decoded query body (application/json) according to the documentation.

enter image description here

enter image description here

Please help me solve the problem. I spent 2 days looking for a solution to my problem on google, yandex, youtube, but I could not find a solution to my problem.

I will be grateful to you in advance for the answer!


Solution

  • The issue you are seeing isn't related to Go (or even Fiber), it's because your form is being posted immediately, the javascript doesn't get a chance to fire.

    You need to add preventDefault(); to stop the event "bubbling up" and triggering a form submit.

    // Bind the call to the variable 'e'
    mybutton.addEventListener("click", (e) => {
       // Add this line!
       e.preventDefault();
    /* ... the rest is the same ... */