英文:
Can't properly serialize forms into a json
问题
我正在尝试使用Golang创建一个Web应用程序,允许您在不同的表单中输入收据的详细信息,然后将这些表单输入序列化为JSON对象。然而,我在序列化表单时遇到了问题,因为每当我尝试“提交”收据时,都会出现错误。
这是main.go文件的内容:
package main
import (
"encoding/json"
"html/template"
"log"
"net/http"
"strconv"
"github.com/gorilla/mux"
)
type Item struct {
ShortDescription string `json:"shortDescription"`
Price string `json:"price"`
}
type Receipt struct {
Retailer string `json:"retailer"`
PurchaseDate string `json:"purchaseDate"`
PurchaseTime string `json:"purchaseTime"`
Items []Item `json:"items"`
Total string `json:"total"`
ReceiptID int `json:"receiptID"`
}
var receiptIDCounter int
var receipts = make(map[int]Receipt)
func main() {
r := mux.NewRouter()
r.HandleFunc("/", homeHandler).Methods("GET")
r.HandleFunc("/submit", submitHandler).Methods("POST")
r.HandleFunc("/receipt/{id}", receiptHandler).Methods("GET")
http.Handle("/", r)
log.Fatal(http.ListenAndServe(":8080", nil))
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("templates/home.html")
if err != nil {
log.Println(err)
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
err = t.Execute(w, nil)
if err != nil {
log.Println(err)
http.Error(w, "Internal server error", http.StatusInternalServerError)
}
}
func submitHandler(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body)
var receipt Receipt
err := decoder.Decode(&receipt)
if err != nil {
log.Println(err)
http.Error(w, "Bad request", http.StatusBadRequest)
return
}
receiptIDCounter++
receipt.ReceiptID = receiptIDCounter
receipts[receipt.ReceiptID] = receipt
jsonResponse, err := json.Marshal(map[string]int{"receiptID": receipt.ReceiptID})
if err != nil {
log.Println(err)
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(jsonResponse)
}
func receiptHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
log.Println(err)
http.Error(w, "Bad request", http.StatusBadRequest)
return
}
receipt, exists := receipts[id]
if !exists {
http.NotFound(w, r)
return
}
t, err := template.ParseFiles("templates/receipt.html")
if err != nil {
log.Println(err)
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
err = t.Execute(w, receipt)
if err != nil {
log.Println(err)
http.Error(w, "Internal server error", http.StatusInternalServerError)
}
}
这是home.html文件,是我的主页的HTML代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Receipt Input Form</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>Receipt Input Form</h1>
<form id="receipt-form">
<label>Retailer:</label>
<input type="text" name="retailer" required><br><br>
<label>Purchase Date:</label>
<input type="date" name="purchaseDate" required><br><br>
<label>Purchase Time:</label>
<input type="time" name="purchaseTime" required><br><br>
<div id="items">
<div class="item">
<label>Short Description:</label>
<input type="text" name="shortDescription[]" required>
<label>Price:</label>
<input type="number" name="price[]" step="0.01" min="0" required>
</div>
</div>
<button type="button" id="add-item-btn">Add Item</button><br><br>
<label>Total:</label>
<input type="number" name="total" step="0.01" min="0" required><br><br>
<button type="submit">Submit</button>
</form>
<script>
$(document).ready(function() {
var itemCount = 1;
$('#add-item-btn').click(function() {
itemCount++;
var newItem = '<div class="item"><label>Short Description:</label>' +
'<input type="text" name="shortDescription[]" required>' +
'<label>Price:</label>' +
'<input type="number" name="price[]" step="0.01" min="0" required>' +
'<button type="button" class="remove-item-btn">Remove Item</button>' +
'</div>';
$('#items').append(newItem);
});
$(document).on('click', '.remove-item-btn', function() {
$(this).parent().remove();
itemCount--;
});
$('#receipt-form').submit(function(event) {
event.preventDefault();
var form = $(this).serializeArray();
var items = [];
$('.item').each(function() {
var item = {};
item.shortDescription = $(this).find('input[name="shortDescription[]"]').val();
item.price = $(this).find('input[name="price[]"]').val();
items.push(item);
});
form.push({ name: "items", value: JSON.stringify(items) });
$.ajax({
type: "POST",
url: "/submit",
data: form,
success: function(response) {
window.location.href = "/receipt?id=" + response.receiptID;
},
error: function(xhr, status, error) {
console.log(xhr.responseText);
}
});
});
});
</script>
</body>
</html>
这是receipt.html文件,是收据提交后显示的HTML代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Receipt Details</title>
</head>
<body>
<h1>Receipt Details</h1>
<ul>
<li>Retailer: {{.Retailer}}</li>
<li>Purchase Date: {{.PurchaseDate}}</li>
<li>Purchase Time: {{.PurchaseTime}}</li>
<li>Items:</li>
<ul>
{{range .Items}}
<li>{{.ShortDescription}} - {{.Price}}</li>
{{end}}
</ul>
<li>Total: {{.Total}}</li>
</ul>
</body>
</html>
我尝试了不同的序列化方式,但没有得到任何有效的结果。当我填写收据表单并点击提交时,我希望能够跳转到显示该收据唯一详细信息的收据页面。然而,我一直收到错误消息,最近的一个错误消息是:invalid character 'r' looking for beginning of value
。
英文:
I'm trying to make a web application in golang that allows you enter in details of a receipt into different forms, then those form inputs get serialized into a json object. However I'm having trouble serializing the forms because whenever I try to "submit" my receipt, I get an error.
This is the main.go
package main
import (
"encoding/json"
"html/template"
"log"
"net/http"
"strconv"
"github.com/gorilla/mux"
)
type Item struct {
ShortDescription string `json:"shortDescription"`
Price string `json:"price"`
}
type Receipt struct {
Retailer string `json:"retailer"`
PurchaseDate string `json:"purchaseDate"`
PurchaseTime string `json:"purchaseTime"`
Items []Item `json:"items"`
Total string `json:"total"`
ReceiptID int `json:"receiptID"`
}
var receiptIDCounter int
var receipts = make(map[int]Receipt)
func main() {
r := mux.NewRouter()
r.HandleFunc("/", homeHandler).Methods("GET")
r.HandleFunc("/submit", submitHandler).Methods("POST")
r.HandleFunc("/receipt/{id}", receiptHandler).Methods("GET")
http.Handle("/", r)
log.Fatal(http.ListenAndServe(":8080", nil))
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("templates/home.html")
if err != nil {
log.Println(err)
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
err = t.Execute(w, nil)
if err != nil {
log.Println(err)
http.Error(w, "Internal server error", http.StatusInternalServerError)
}
}
func submitHandler(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body)
var receipt Receipt
err := decoder.Decode(&receipt)
if err != nil {
log.Println(err)
http.Error(w, "Bad request", http.StatusBadRequest)
return
}
receiptIDCounter++
receipt.ReceiptID = receiptIDCounter
receipts[receipt.ReceiptID] = receipt
jsonResponse, err := json.Marshal(map[string]int{"receiptID": receipt.ReceiptID})
if err != nil {
log.Println(err)
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(jsonResponse)
}
func receiptHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
log.Println(err)
http.Error(w, "Bad request", http.StatusBadRequest)
return
}
receipt, exists := receipts[id]
if !exists {
http.NotFound(w, r)
return
}
t, err := template.ParseFiles("templates/receipt.html")
if err != nil {
log.Println(err)
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
err = t.Execute(w, receipt)
if err != nil {
log.Println(err)
http.Error(w, "Internal server error", http.StatusInternalServerError)
}
}
This is my home.html which the html for my homepage
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Receipt Input Form</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>Receipt Input Form</h1>
<form id="receipt-form">
<label>Retailer:</label>
<input type="text" name="retailer" required><br><br>
<label>Purchase Date:</label>
<input type="date" name="purchaseDate" required><br><br>
<label>Purchase Time:</label>
<input type="time" name="purchaseTime" required><br><br>
<div id="items">
<div class="item">
<label>Short Description:</label>
<input type="text" name="shortDescription[]" required>
<label>Price:</label>
<input type="number" name="price[]" step="0.01" min="0" required>
</div>
</div>
<button type="button" id="add-item-btn">Add Item</button><br><br>
<label>Total:</label>
<input type="number" name="total" step="0.01" min="0" required><br><br>
<button type="submit">Submit</button>
</form>
<script>
$(document).ready(function() {
var itemCount = 1;
$('#add-item-btn').click(function() {
itemCount++;
var newItem = '<div class="item"><label>Short Description:</label>' +
'<input type="text" name="shortDescription[]" required>' +
'<label>Price:</label>' +
'<input type="number" name="price[]" step="0.01" min="0" required>' +
'<button type="button" class="remove-item-btn">Remove Item</button>' +
'</div>';
$('#items').append(newItem);
});
$(document).on('click', '.remove-item-btn', function() {
$(this).parent().remove();
itemCount--;
});
$('#receipt-form').submit(function(event) {
event.preventDefault();
var form = $(this).serializeArray();
var items = [];
$('.item').each(function() {
var item = {};
item.shortDescription = $(this).find('input[name="shortDescription[]"]').val();
item.price = $(this).find('input[name="price[]"]').val();
items.push(item);
});
form.push({ name: "items", value: JSON.stringify(items) });
$.ajax({
type: "POST",
url: "/submit",
data: form,
success: function(response) {
window.location.href = "/receipt?id=" + response.receiptID;
},
error: function(xhr, status, error) {
console.log(xhr.responseText);
}
});
});
});
</script>
</body>
</html>
This is my receipt.html which is the html for the receipt page after the receipt gets submitted.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Receipt Details</title>
</head>
<body>
<h1>Receipt Details</h1>
<ul>
<li>Retailer: {{.Retailer}}</li>
<li>Purchase Date: {{.PurchaseDate}}</li>
<li>Purchase Time: {{.PurchaseTime}}</li>
<li>Items:</li>
<ul>
{{range .Items}}
<li>{{.ShortDescription}} - {{.Price}}</li>
{{end}}
</ul>
<li>Total: {{.Total}}</li>
</ul>
</body>
</html>
I've tried different ways of serialization but haven't got anything to work. When I fill out the forms for the receipt then hit submit, I expect that I get taken to the receipt page showing unique details for that receipt. However I'm just getting an error, my most recent one being this:
invalid character 'r' looking for beginning of value
答案1
得分: 0
请将您的home.html
更新如下。我将提交请求的Content-Type更改为application/json
,因为服务器中的submitHandler
正在寻找一个JSON
。
$('#receipt-form').submit(function(event) {
event.preventDefault();
var form = $(this).serializeArray();
var formObject = {};
$.each(form,
function(i, v) {
if (v.name != "price[]" && v.name != "shortDescription[]") {
formObject[v.name] = v.value;
}
});
var items = [];
$('.item').each(function() {
var item = {};
item.shortDescription = $(this).find('input[name="shortDescription[]"]').val();
item.price = $(this).find('input[name="price[]"]').val();
items.push(item);
});
formObject["items"] = items;
$.ajax({
type: "POST",
url: "/submit",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(formObject),
success: function(response) {
window.location.href = "/receipt?id=" + response.receiptID;
},
error: function(xhr, status, error) {
console.log(xhr.responseText);
}
});
});
英文:
Please update your home.html
as below. I changed submit request Content-Type to application/json
because submitHandler
in the server is looking for an JSON
.
$('#receipt-form').submit(function(event) {
event.preventDefault();
var form = $(this).serializeArray();
var formObject = {};
$.each(form,
function(i, v) {
if (v.name != "price[]" && v.name != "shortDescription[]") {
formObject[v.name] = v.value;
}
});
var items = [];
$('.item').each(function() {
var item = {};
item.shortDescription = $(this).find('input[name="shortDescription[]"]').val();
item.price = $(this).find('input[name="price[]"]').val();
items.push(item);
});
formObject["items"] = items;
$.ajax({
type: "POST",
url: "/submit",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(formObject),
success: function(response) {
window.location.href = "/receipt?id=" + response.receiptID;
},
error: function(xhr, status, error) {
console.log(xhr.responseText);
}
});
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论