質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.33%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

230閲覧

react-fook-formのonSubmitでRust AxumへPostすると、422 (Unprocessable Entity)エラー

DeepRoastBeans

総合スコア83

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

1クリップ

投稿2025/02/07 06:36

実現したいこと

Rust Axumで実装するアプリケーションのログイン画面などのフォームバリデーションをreact-fook-formで実装したい

発生している問題・分からないこと

入力フォームから送信ボタンを押してPostしようとすると、422 (Unprocessable Entity) エラーが発生し、Postできない。
Reactと、Rust Axumのソースコードは以下の通りです。

エラーメッセージ

error

1http://192.168.33.10:3000/login 422 (Unprocessable Entity) 2 3※↑入力フォーム側のConsole上のエラーメッセージ。Axum側では、以下のようにRunningとなったままで、Requestを受け付けたログなどははかれていない。 4 5 Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.77s 6 Running `target/debug/axum`

該当のソースコード

React

1import './App.css'; 2import { useForm } from 'react-hook-form'; 3import React from 'react'; 4 5function App() { 6 const { register, 7 handleSubmit, 8 formState: {errors}, 9 } = useForm({ 10 criteriaMode: 'all', 11 }); 12 13 const onSubmit = (data) => { 14 const formData = new FormData(data); 15 // formData.append("username", data.username); 16 // formData.append("password", data.password); 17 fetch("./login", { 18 method: "POST", 19 headers: { 20 "Content-Type": "application/x-www-form-urlencoded", 21 }, 22 body: formData 23 }); 24 console.log(formData); 25 }; 26 27 return ( 28 <div className="App"> 29 <form onSubmit={handleSubmit(onSubmit)}> 30 <div class="mb-3 mt-3"> 31 <input type="text" class="form-control" placeholder="user name" {...register('username', { 32 required: { 33 value: true, 34 message: 'This is a required field.', 35 }, 36 minLength: { 37 value: 6, 38 message: 'Please enter at least 6 characters.' 39 }, 40 maxLength: { 41 value: 20, 42 message: 'Please enter less than 20 characters.' 43 }, 44 pattern: { 45 value: /^[A-Za-z0-9_]+$/, 46 message: 'Please enter alphanumeric characters only.' 47 } 48 })}/> 49 {errors.username?.type === 'required' && (<div class="fs-s error-msg">{errors.username.types.required}</div>)} 50 {errors.username?.type === 'minLength' && (<div class="fs-s error-msg">{errors.username.types.minLength}</div>)} 51 {errors.username?.type === 'maxLength' && (<div class="fs-s error-msg">{errors.username.types.maxLength}</div>)} 52 {errors.username?.type === 'pattern' && (<div class="fs-s error-msg">{errors.username.types.pattern}</div>)} 53 </div> 54 <input type="password" class="form-control" placeholder="password" {...register('password', { 55 required: { 56 value: true, 57 message: 'This is a required field.', 58 }, 59 minLength: { 60 value: 8, 61 message: 'Please enter at least 8 characters.' 62 }, 63 maxLength: { 64 value: 25, 65 message: 'Please enter less than 25 characters.' 66 }, 67 pattern: { 68 value: /^[A-Za-z0-9_]+$/, 69 message: 'Please enter alphanumeric characters only.' 70 } 71 })}/> 72 {errors.password?.type === 'required' && (<div class="fs-s error-msg">{errors.password.types.required}</div>)} 73 {errors.password?.type === 'minLength' && (<div class="fs-s error-msg">{errors.password.types.minLength}</div>)} 74 {errors.password?.type === 'maxLength' && (<div class="fs-s error-msg">{errors.password.types.maxLength}</div>)} 75 {errors.password?.type === 'pattern' && (<div class="fs-s error-msg">{errors.password.types.pattern}</div>)} 76 <span class="fs-s">If you don't have account, you can <a href="/signup">Sign up</a>.</span><br/> 77 <input type="submit" class="btn submit" value="login" /> 78 </form> 79 </div> 80 ); 81} 82 83export default App;

Rust

1#[derive(Serialize, Deserialize)] 2struct LoginForm { 3 username: String, 4 password: String, 5} 6 7#[tokio::main] 8async fn main() { 9 10 let serve_dir = ServeDir::new("static").not_found_service(ServeFile::new("static")); 11 12 let app = Router::new() 13 .route("/", get(handle_index)) 14 .route("/login", post(handle_api)) 15 .nest_service("/static", serve_dir.clone()) 16 .fallback_service(serve_dir); 17 18 let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); 19 axum::serve(listener, app).await.unwrap(); 20} 21 22async fn handle_api(axum::Form(loginform): axum::Form<LoginForm>)-> axum::response::Html<String> { 23 24 let tera = tera::Tera::new("templates/*").unwrap(); 25 26 let mut context = tera::Context::new(); 27 context.insert("title", "Index page"); 28 29 let output = tera.render("app.html", &context); 30 axum::response::Html(output.unwrap()) 31}

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

Rust Axum側は、普通のHTMLファイルのformの場合は問題なくデータを受け取ることができるので、Reactの onSubmit の中の書き方が問題ではないかと色々試したが、うまくいなかい。

最初、new FormData(data); とせずに、body: data としていたが、うまくいなかった。

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

JSON データの形式が間違っているか、必須フィールドが欠落している可能性があります。 JSON 構造を再確認し、必要なフィールドがすべて含まれており、正しく入力されていることを確認してください。

投稿2025/02/07 08:50

thomas598brown

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

DeepRoastBeans

2025/02/08 12:39

ありがとうございます。onSubmitで送るデータをFormDataではなくJson形式に変更し、axum側もjsonで受け取るようにしたら、POSTできました。以下はソースコードの修正箇所です。 ただ、作っているアプリケーションで、一部の入力フォームでファイルのアップロードもあるので、全てjson形式でPostするという仕様は厳しそうな気がしています。。一応解決しましたので、クローズします。 // react const onSubmit = (data) => { var formData = JSON.stringify(data); fetch("./login", { method: "POST", headers: { "Content-Type": "application/json", }, body: formData }) .then( window.location = './home' ) console.log(formData); }; // axum async fn handle_login(Json(payload): Json<LoginForm>) { let username = payload.username; let password = payload.password; println!("username:{}, password:{}", username, password); } // コマンドライン $ cargo run Compiling axum v0.1.0 (/home/vagrant/dev/rust/axum) Finished `dev` profile [unoptimized + debuginfo] target(s) in 5.13s Running `target/debug/axum` username:asdfggggg, password:asdfggggg
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.33%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問