我遇到了一个非常奇怪的问题,我的ajax post请求在页面加载后第一次运行良好,但如果我在不刷新页面的情况下再次提交表单,那么内容将返回到整个页面,而不仅仅是更新DIV。我花了数天时间寻找答案,并通过反复尝试,我怀疑问题与
Request.Headers["X-Requested-With"]
第二次提交时为空。注意,我将视图组件返回到ajax请求,我的ajax代码在单独的js文件中。
视图组件(它包含在ajax请求返回时提交和替换的表单。在页面加载或刷新后,它可以正常工作)
@model MSIC.Models.ClientViewModels.VisitMovementViewModel
@{
bool inProgress = (bool)ViewData["inProgress"];
}
<form asp-controller="Client" asp-action="VisitMovement" asp-route-id="@Model.VisitMovementID" id="formVisitAction" method="post" onsubmit="AjaxSubmit(this)">
<input asp-for="VisitID" type="hidden" />
<input asp-for="StageNo" type="hidden" />
<input type="hidden" id="replaceID" name="replaceID" value="#ClientVisit" />
<input type="hidden" id="submitAction" name="submitAction" />
<div class="col-md-9 no-padding">
<input type="text" id="visitMovementComment" name="visitMovementComment" class="form-control" placeholder="Comment..." required>
</div>
<div class="input-group col-md-3">
<input type="text" id="visitMovementBoothNo" name="visitMovementBoothNo" class="form-control" placeholder="Booth..." required>
<div class="input-group-btn">
<button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" @((inProgress) ? "" : "disabled")>Action <span class="caret"></span></button>
<ul class="dropdown-menu dropdown-menu-right">
@if (Model.Buttons != null)
{
foreach (var item in Model.Buttons)
{
if (item.beforeDivider)
{
<li><button type="@item.Type" name="@item.Name" class="btn btn-link btn-block btn-flat" value="@item.Value" onclick="@item.OnClick">@item.Text</button></li>
}
}
<li role="separator" class="divider"></li>
foreach (var item in Model.Buttons)
{
if (!item.beforeDivider)
{
<li><button type="@item.Type" name="@item.Name" class="btn btn-link btn-block btn-flat" value="@item.Value" onclick="@item.OnClick">@item.Text</button></li>
}
}
}
</ul>
</div>
</div>
</form>
Ajax请求位于单独的JS文件中(在调试时,一切都会按预期运行,但在视图组件返回后,表单第二次提交后,成功、错误、完整函数不会触发,返回的数据将加载到整个页面)
function AjaxSubmit(form) {
$form = $(form);
var replaceID = $('input#replaceID', $form).val();
var formData = $form.serialize();
if (!$form[0].checkValidity()) {
return false;
}
$form.submit(function (e) {
e.preventDefault();
$.ajax({
url: $form.attr('action'),
type: $form.attr('method'),
data: formData,
async: true,
processData: false,
cache: false,
success: function (data) {
$(replaceID).html(data);
},
error: function (xhr, status, error) {
console.log(xhr.status + " - " + error);
},
complete: function (data) {
console.log(data);
}
});
});
}
行动方法(我怀疑问题可能与
请求.标题[“X-Requested-With”]
在第二次提交时为空,因此MVC没有意识到这是一个ajax请求,因此将结果返回到页面,而不是返回到ajax请求)
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> VisitMovement(int id, int submitAction, int? visitMovementBoothNo, string visitMovementComment, VisitMovementViewModel model)
{
var test1 = Request.ContentType; //1ST REQUEST = "application/x-www-form-urlencoded; charset=UTF-8", 2ND REQUEST = "application/x-www-form-urlencoded"
var test2 = Request.Headers["X-Requested-With"]; //1ST REQUEST = "XMLHttpRequest", 2ND REQUEST = Empty
try
{
if (ModelState.IsValid)
{
bool complete = false;
switch (submitAction)
{
case 2: //Proceed to Stage 2
model.StageNo = 2;
break;
case 3: //Proceed to Stage 3
model.StageNo = 3;
break;
case 4: //Complete Visit
complete = true;
break;
default:
return BadRequest("Could not determine action.");
}
await visitAPI.VisitMovement(id, model.VisitID, submitAction, model.StageNo, visitMovementBoothNo, visitMovementComment, complete);
return ViewComponent("ClientVisit", new { visitID = model.VisitID });
}
else
{
return BadRequest(ModelState);
}
}
catch (Exception ex)
{
return StatusCode(500, ex.Message);
}
}
如果我的假设是正确的,为什么ajax请求在第二次提交时没有发送正确的头,我如何修复它?如果不是,还有什么问题?