有一个smartcontract
GovtContract
,在使用curl
命令时可以正常工作,
$curl -X POST -H "Content-Type: application/json" localhost:3000/govtcontract/set -d '{"value":"5"}' | jq
$curl -X GET -H "Content-Type: application/json" localhost:3000/govtcontract/get | jq
但是,当使用表单时,无法在请求标头中将内容类型设置为JSON。
HTML和JS:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
function validateForm() {
console.log("in validateForm");
//var amt = document.forms["txForm"]["amtvalue"].value;
var amt = document.getElementById("amtvalue").value;
console.log(amt);
if (isNaN(amt) || amt < 0) {
alert("Amount is not valid");
return false;
}
console.log("before ajax call");
var sendValues = {
value: amt
}
$.ajax({
url: "/govtcontract/set",
type: "POST",
dataType:"json",
data: JSON.stringify({
value: amt
}),
contentType: "application/json",
success: function(got) {
return console.log("shortened url: " + got);
}
});
return true;
}
</script>
</head>
<body>
<h1>Enter the transaction details below:</h1>
<form name="txForm" action="http://127.0.0.1:3000/govtcontract/set" onsubmit="return validateForm()" method="post">
Enter the amount:<br>
<input type="number" name="amtvalue" id="amtvalue" value="0"/><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
服务器app.js
:
const bodyParser = require('body-parser');
const express = require('express');
const GovtContractInstance = new (require('./GovtContract.js'))();
const app = express();
// Uses json as the format for reading request bodies
app.use(bodyParser.json());
// Allow CORS policy to allow anyone to call these endpoints
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// POST testing endpoint for echoing the body of post calls
// You can use this endpoint to ensure the format of your curl requests are correct
// ex: curl -X POST -H "Content-Type: application/json" localhost:3000/echo -d '{"copy": "cat"}'
app.post('/echo', (request, response) => {
// Same as post call except used for /app endpoint for getting/initializing the backend data
response.status(200).send(request.body);
});
// POST deploys the SimpleStorage.sol smart contract onto your network.
// ex: curl -X POST -H "Content-Type: application/json" localhost:3000/simplestorage/deploy
// Optionally, you can use a SimpleStorage contract that it already deployed by
// adding the deployed address to the end of the url
// ex. curl -X POST -H "Content-Type: application/json" localhost:3000/simplestorage/deploy/0xafcAfc6F48E23cEF78355A2f6D013310B84c6272
app.post('/govtcontract/deploy/:address?', (request, response) => {
let address = request.params.address ? request.params.address : null;
GovtContractInstance.deploy(address).then((deployedAddress) => {
return response.status(200).send({contractAddress: deployedAddress});
}).catch((error) => {
console.log("Error in deploy: ", error);
return response.status(400).send({errorMessage: JSON.stringify(error)});
})
});
// POST Sets the value stored in the contact to the value set in the request body
// ex: curl -X POST -H "Content-Type: application/json" localhost:3000/simplestorage/set -d '{"value": "5"}'
app.post('/govtcontract/set', (request, response) => {
if (!request.body.value) {
return response.status(400).send({errorMessage: "No value set in request body"});
}
GovtContractInstance.set(request.body.value).then((txReceipt) => {
return response.status(200).send({receipt: txReceipt});
}).catch((error) => {
console.log(error);
return response.status(400).send({errorMessage: JSON.stringify(error)});
})
});
// GET Returns the value stored in the contract
// ex: curl -X GET -H "Content-Type: application/json" localhost:3000/simplestorage/get
app.get('/govtcontract/get', (request, response) => {
GovtContractInstance.get().then((value) => {
return response.status(200).send({storedValue: value});
}).catch((error) => {
console.log(error);
return response.status(400).send({errorMessage: JSON.stringify(error)});
})
});
// Listen on port 3000
app.listen(3000, () => {
console.log('listening on port 3000');
});
如请求标头所示,表单以application/x-www-form-urlencoded
的形式发送。无法解决这个问题。 TIA!
答案 0 :(得分:0)
您使用JSON.stringify()
返回一个字符串。
您只需要在data属性中传递一个对象
{
...
data: { value : amt },
...
}
答案 1 :(得分:0)
欢迎堆栈溢出。
您的通话有多个问题。您出于相同的目的使用FORM
提交和AJAX
调用。仅使用其中之一。使用AJAX
通话,您将能够维护单页应用程序,因此我的解决方案将仅专注于此。
由于我们使用的是AJAX
调用,因此无需进行表单和表单操作,因为AJAX
网址会处理这些问题。
HTML和JS:
<html>
<head>
</head>
<body>
<h1>Enter the transaction details below:</h1>
Enter the amount:<br>
<input type="number" name="amtvalue" id="amtvalue" value="0"/><br>
<p onClick="validateForm();">Submit</p>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
function validateForm() {
console.log("in validateForm");
var amt = document.getElementById("amtvalue").value;
console.log(amt);
if (isNaN(amt) || amt < 0) {
alert("Amount is not valid");
return false;
}
console.log("before ajax call");
$.ajax({
url: "/govtcontract/set",
method: "POST",
headers: {
'Content-Type': 'application/json'
},
data: {
value: amt
},
success: function(got) {
console.log("shortened url: " + got);
}
});
}
</script>
</html>
还在服务器app.js
上添加以下内容,以获取req.body
中的任何类型的数据
// configure the app to use bodyParser() to extract body from request.
// parse urlencoded types to JSON
app.use(bodyParser.urlencoded({
extended: true
}));
// parse various different custom JSON types as JSON
app.use(bodyParser.json({ type: 'application/*+json' }));
// parse some custom thing into a Buffer
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
// parse an HTML body into a string
app.use(bodyParser.text({ type: 'text/html' }));
有关使用NodeJS和HTML的Web应用程序的入门指南,请访问this repository,它说明了单页应用程序以及多页和单页之间的区别。