我想從客戶端提交一筆交易到以太坊區塊鏈,取回交易哈希,然后將此哈希提交到我的后端。
在前端,我有一個這樣的表格:
<form id="formConfirm" method="POST" action="/step2" onSubmit="processStep1">
<input id="textWalletAddress" name="walletAddress" type="text" readonly />
<input id="textEncodedFunctionCall" th:value="${encodedFunctionCall}" readonly />
<input type="text" id="textTxHash" readonly />
<input type="submit" value="Submit" />
</form>
在函式內部,我想提交交易,取回相應的哈希,并用它填充一個欄位,以便我可以將它推送到我的后端。
async function processStep1(e) {
// edit1: trying out preventDefault
alert('Before preventDefault');
e.preventDefault();
alert('After preventDefault');
let efc = document.getElementById('textEncodedFunctionCall').value;
let walletAddress = document.getElementById('textWalletAddress').value;
const txParams = {
to: CONTRACT,
from: walletAddress,
'data': efc
};
if (window.ethereum) {
try {
const txHash = await window.ethereum.request({
method: "eth_sendTransaction",
params: [txParams]
});
document.getElementById('textTxHash').value = txHash;
// how/where do I preventDefault()?
} catch (err) {
alert('ERROR! ' err);
}
} else {
alert('MetaMask is not installed!');
}
}
我遇到的問題是表單在沒有哈希的情況下繼續提交。交易確實通過了(帶有 MetaMask 提示和所有),但在我的后端我得到了一個錯誤。
我讀到我應該這樣做,preventDefault()但我不知道如何應用它。有人可以指導我如何做到這一點嗎?當我試圖減少對外部庫的依賴時,純 JavaScript 將是最理想的。
Edit1:我preventDefault一開始就嘗試過,但我什至沒有看到任何警報。
Edit2: Added the fields that were missing in my question
uj5u.com熱心網友回復:
好吧,我會選擇:
- 洗掉
onSubmit="processStep1()"并用 javascript: 替換它document.getElementById('formConfirm').onsubmit = processStep1;。注意這里的不足()!編輯:正如有人已經指出的那樣,洗掉 () inonSubmit="processStep1()"也應該可以解決問題 - 然后,您的函式獲取一個事件作為引數,您可以這樣做
async function processStep1(event) { ... } - 現在最后一件事是在開始時呼叫
event.preventDefault()某處。請記住,您正在阻止默認操作,因此您沒有提交表單 - 您可能希望使用fetch()手動提交表單。
除此之外,您可以input type="submit"在單擊時使用自定義按鈕替換您的功能,因此您不必呼叫event.preventDefault(). 但imo沒有太大區別。
uj5u.com熱心網友回復:
一些錯誤:
onSubmit接受一個函式而不是函式呼叫,所以它應該是:
<form ... onSubmit="processStep1"> ...
- 如果你想停止表單動作,你需要呼叫
preventDefault事件的方法,這會阻止瀏覽器首先聯系表單動作:
async function processStep1(event) {
// I suggest as first row so you are sure
// the form will stop before any other operation/error
// made by this function
event.preventDefault();
...
- 然后,您需要使用
XHR(XMLHttpRequest - MDN)呼叫后端,因為您停止了瀏覽器將完成的正常呼叫(通過阻止事件的默認值):
function sendForm(form) {
var formData = new FormData();
var inputs = form.querySelectorAll('input');
inputs.forEach(function(input) {
var data;
// simplified version for files (since it seems you don't need it)
if (input.type === 'file') { data = input.files[0]; }
else { data = input.value; }
formData.append(input.name, data);
});
return new Promise(function(y, n) {
var xhr= new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (status === 0 || (status >= 200 && status < 400)) {
y(xhr.responseText);
}
else { n(xhr); }
};
xhr.open(form.method, form.action);
xhr.send(formData);
});
}
async function processStep1(event) {
...
// at the end of your function
try {
var response = await sendForm(this);
// threat response
} catch(ex) {
/// threat exceptions
}
}
有關FormData Object(MDN)的更多資訊,我建議您點擊鏈接以獲得更好的閱讀。
uj5u.com熱心網友回復:
這里。我只是把整個代碼。
<!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>Document</title>
</head>
<body>
<form id="formConfirm">
<input id="textWalletAddress" name="walletAddress" type="text" />
<input id="textEncodedFunctionCall" th:value="${encodedFunctionCall}" />
<input type="text" id="textTxHash" readonly />
<input type="submit" value="Submit" />
</form>
<script>
const form = document.getElementById("formConfirm")
async function processStep1(e) {
// let efc = document.getElementById("textEncodedFunctionCall").value
// let walletAddress = document.getElementById("textWalletAddress").value
// const txParams = {
// to: CONTRACT,
// from: walletAddress,
// data: efc,
// }
// if (window.ethereum) {
// try {
// const txHash = await window.ethereum.request({
// method: "eth_sendTransaction",
// params: [txParams],
// })
// document.getElementById("textTxHash").value = txHash
// // how/where do I preventDefault()?
// } catch (err) {
// alert("ERROR! " err)
// }
// } else {
// alert("MetaMask is not installed!")
// }
document.getElementById("textTxHash").value = "HASH"
}
form.addEventListener("submit", async function (e) {
e.preventDefault()
await processStep1()
})
</script>
</body>
</html>
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/443841.html
標籤:javascript async-await form-submit
上一篇:需要想法如何決議以下JSON格式
