Actix: How to make post and get in the same page?

I have following code:

use std::time;

use actix_web::{
    middleware, web, App, HttpRequest, HttpResponse, HttpServer, Responder, Result,
    get,
    post,
    http::{
        header::{self ,ContentType},
        Method, StatusCode,
    }
};
use actix_files::Files;
use serde::{Serialize, Deserialize};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .service(get_html)
            .service(show_result)
    })
    .bind(("127.0.0.1", 8081))?
    .run()
    .await
}

#[get("/")]
async fn get_html() -> impl Responder {
    HttpResponse::Ok()
        .content_type("text/html")
        .body(include_str!("../../form2.html"))
}

#[post("/result")]
async fn show_result(params: web::Form<InputCodes>) -> impl Responder {
    let res =  format!("your input is {}, and I have got it in {:?}", params.name, time::Instant::now());

    HttpResponse::Ok()
        .content_type("text/palin")
        .body(res)
}

#[derive(Serialize, Deserialize)]
pub struct InputCodes {
    pub name: String
}

And the form2.html contains these:

<!doctype html>
<html>

<head>
    <title>Online Strategy</title>
</head>

<body>
    <form action='/result' method=POST>
        <textarea id="editor" name="name"></textarea>
        <button type=submit>Run</button>
    </form>
    <textarea id="editor2" name="nam2"></textarea>
</body>

</html>

The process works as following:

  1. I open the url 127.0.0.1:8081, it show this web page
    图片
  2. I click the Run button, then the page jump to 127.0.0.1:8081/result, which show async fun show_result's result.
  3. I am trying to show the result(from step 2) in the second textarea(instead of 127.0.0.1:8081/result page), like this
    图片

How can I define the show_result function to get it?

The problem is not with your backend but with how the browser handles submitting a form to /result. What happens is your browser makes a request POST /result, puts the form data in the request's body and renders the response as the new webpage. What you'd normally do when /result is an endpoint that serves some data instead of a webpage you wish to render is using JavaScript to make the request. This allows you to handle the rendering yourself, instead of the browser handling it for you. You should probably have a look at fetch or XMLHttpRequest and use one of those to make your request to /result, instead of using the form's submit functionality.

Or if this is too vanilla for you, you could look into frontend frameworks more suited for your kind of interactive webapp. There are a ton of JS-based ones like React, Svelte, Vue, Angular, etc. but also very exiting new ones based on WebAssembly including a very neat looking one written in and for Rust: yew.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.