[英]How do I send javascript https post or webhook from static html web page form?
[英]How do I send a complex JSON object from an HTML form using SYNCHRONOUS page POST?
我的服務器正在使用 ServiceStack 並希望接收一些這樣的數據:
{
Customer: {
Company: "TheCompany",
RegionCode: "AU_NSW"
},
Name: {
First: "Jimi",
Last: "Hendrix"
}
}
我有一個包含這些字段的表單,我可以使用 JQuery 輕松獲取數據,制作嵌套的 JSON 對象並使用 $.post 發送它。
但我不想將它作為 AJAX 發送,因為我希望整個頁面都提交,然后瀏覽器將服務器的響應顯示為一個新頁面。 只是經典的表單發布行為。
我嘗試將復雜的 json 作為字符串嵌入隱藏表單字段中 - 沒有雪茄。
我還查看了 ServiceStack 是否有任何命名約定,以便我可以將我的表單字段稱為“Name[First]”,並讓 ServiceStack 在其正確的嵌套結構中放置正確的值 - 也沒有雪茄。
雖然 Mythz 建議發布 JSV 值是可行的,但有時在 JavaScript 中構建和維護復雜的 JSV 會很麻煩。 例如,您可能必須處理轉義用戶輸入的數據,並且語法問題可能難以跟蹤
這個解決方案看起來很復雜,但實際上並不復雜,並且高度可重用,只需要您可以發送編碼的 JSON,這在 jQuery 中非常簡單。
JSON.stringify(data)
Data
字段的值發送Data
字段的 JSON 值反序列化為您的 DTO我的解決方案在表單發布中將編碼為 JSON 的 DTO 對象發送到服務。 然后一個簡單的過濾器攔截請求並從 JSON 負載填充 DTO。
public class GetFromJsonVariableAttribute : Attribute, IHasRequestFilter
{
string _variableName;
public GetFromJsonVariableAttribute(string variableName = "Data")
{
_variableName = variableName;
}
public void RequestFilter(IRequest req, IResponse res, object requestDto)
{
// Convert the JSON payload to DTO format
var payload = req.GetParam(_variableName);
if(payload != null)
requestDto = JsonSerializer.DeserializeFromString(payload, requestDto.GetType());
}
public int Priority { get { return int.MinValue; } }
IHasRequestFilter IHasRequestFilter.Copy() { return this; }
}
然后使用您只需將該屬性添加到您的 DTO。 Data
是將保存 JSON 有效負載的表單變量的名稱。 您可以在此處選擇您想要的任何名稱。
[GetFromJsonVariable("Data")]
[Route("/Customers","POST")]
public class CreateCustomerRequest : IReturnVoid
{
public Customer Customer { get; set; }
public Name Name { get; set; }
}
$("#CreateCustomer").on("submit", function(){
// Get the form values into simple key value array
var values = {};
$.each($(this).serializeArray(), function(){ values[this.name] = this.value; });
// Prepare the DTO
var data = {
Customer: {
Company: values["Company"],
RegionCode: values["RegionCode"]
},
Name: {
First: values["First"],
Last: values["Last"]
}
};
// Convert it to JSON
$('#PayloadForm [name="Data"]').val(JSON.stringify(data));
$('#PayloadForm').submit();
return false;
});
使用 HTML 創建您的用戶將與之交互的表單,無需任何操作,但鏈接到 jQuery 提交事件代碼; 還有一個隱藏的表單,它將實際執行同步 POST。 請注意,屬性Data
與應在其上接收有效負載的屬性相匹配
<form id="CreateCustomer">
<input type="text" name="Company" value="TheCompany" /><br/>
<input type="text" name="RegionCode" value="AU_NSW" /><br/>
<input type="text" name="First" value="Jimi" /><br/>
<input type="text" name="Last" value="Hendrix" /><br/>
<input type="submit" value="Submit" />
</form>
<!-- This form is hidden -->
<form action="/Customers" method="POST" id="PayloadForm">
<input type="hidden" name="Data" value="">
</form>
ServiceStack 可以使用 JSV 格式 POST 復雜類型,例如:
<input name="Customer" value="{Company:TheCompany,RegionCode:AU_NSW}" />
<input name="Name" value="{First:Jimi,Last:Hendrix}" />
否則,您可以使用 JSON 發送復雜類型,例如使用 jQuery 的 $.ajax:
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
url: "http://host/myservice",
dataType: 'json',
data: JSON.stringify({Customer:{Company:'x',RegionCode:'x'}}),
success: function(response){ ... }
});
雖然為了最大的互操作性,你應該努力保持你的請求 DTO 的扁平化,例如:
<form id="theForm" ...>
<input name="Company" value="TheCompany" />
<input name="RegionCode" value="AU_NSW" />
<input name="FirstName" value="Jimi" />
<input name="LastName" value="Hendrix" />
</form>
然后您可以按原樣 POST 瀏覽器將使用x-www-form-urlencoded
Content-Type 執行的操作,甚至可以使用ServiceStack 的 ss-utils.js bindForm 方法進行 ajaxify ,例如:
$("#theForm").bindForm();
將提交處理程序附加到表單,該處理程序將 JSON 作為表單中預先創建的隱藏輸入字段的值。
$(form_to_submit).on('submit', function() {
$(form_to_submit).find(hidden_input).val(json_value);
});
要使用 jQuery 提交表單,請使用:
$(form_to_submit).submit();
我在這里使用 NodeJS 和 Express Server 時遇到了同樣的事情。 我想發布一個復雜的 JSON 對象,該對象是我在用戶在客戶端進行選擇時構建的。 然后我將一個 onClick 事件附加到一個調用我的 SubmitForm 函數的按鈕。
您的數據可以是任何 JSON 對象。 只要確保在服務器端解析它。
function Param(name, value){
var hiddenField = document.createElement('input');
hiddenField.setAttribute('type', 'hidden');
hiddenField.setAttribute('name', name);
hiddenField.setAttribute('value', value);
return hiddenField;
}
function SubmitForm(data){
var form = document.createElement('form');
form.setAttribute('method', 'post');
form.setAttribute('action', '/route');
form.appendChild(Param('data', JSON.stringify(data)));
document.body.appendChild(form);
form.submit();
}
此外,這是純 javascript。 對於那些喜歡消除開銷的人,這里沒有隱藏的 HTML 或 jQuery。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.