目录
参考资料:
Razor Page 后台代码:
/Pages/Books/Index.cshtml.cspublic async TaskOnGetBookListAsync()
{
var bookDtos = await _bookAppService.GetListAsync(new PagedAndSortedResultRequestDto() { });
return new JsonResult(bookDtos);
}
js调用
/Pages/Books/Index.js$.ajax({
type: 'GET',
url: "?handler=BookList",
})
url的规则是:?handler= 加上 OnGetBookListAsync 中的BookListPOST请求
发起post请求时,Asp.Net Core 为了防止 XSSh和 CSRF引发的网站安全问题, js 直接访问后台代码是会报错的Razor Pages 由防伪造验证保护,FormTagHelper 将防伪造令牌注入 HTML 窗体元素,防止跨站点请求伪造 (XSRF/CSRF)。
XSS:跨站脚本(Cross-site scripting,通常简称为XSS)是一种网站应用程序的安全漏洞***,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类***通常包含了HTML以及用户端脚本语言。
CSRF:跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的***方法。
由于以上的问题,直接ajax post请求会出错
首先,在Startup.cs的ConfigureServices()方法中,添加:services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
然后在/Pages/Books/Index.cshtml中添加@Html.AntiForgeryToken()
/Pages/Books/Index.cshtml中定义POST 方法public async TaskOnPostDeleteBookAsync(string id)
{
await _bookAppService.DeleteAsync(new Guid(id));
return NoContent();
}
最后js调用:let params = {
"id": data.record.id
};
$.ajax({
type: 'POST',
//contentType: 'application/json',
headers: {
"XSRF-TOKEN": $('input:hidden[name="__RequestVerificationToken"]').val()
},
url: `?handler=DeleteBook`,
data: params
}).then(function () {
})
注意:解决Asp.Net Core 为了防止 XSSh和 CSRF引发的网站安全问题, js 直接问后台代码是会报错的问题:headers: {
"XSRF-TOKEN": $('input:hidden[name="__RequestVerificationToken"]').val()
},不能是 contentType: 'application/json', 而是取默认值: contentType: 'application/x-www-form-urlencoded'
后台方法:public async TaskOnPostDeleteBookAsync(string id) {....}
id 的类型也可以是Guidpublic async TaskOnPostDeleteBookAsync(Guid id)
,前端js传id时值为string,Asp.net Core框架能自动转化为Guid类型POST对象参数
有时,POST请求参数是一个对象,
Razor Page 后台代码:
/Pages/Books/Index.cshtml.cspublic async TaskOnPostDeleteBookAsync(DeleteBookViewModel vm)
{
//await _bookAppService.DeleteAsync(new Guid(id));
await _bookAppService.DeleteAsync(vm.id);
return NoContent();
}
public class DeleteBookViewModel
{
public Guid id { get; set; }
public string msg { get; set; }
}
js调用
/Pages/Books/Index.jslet params = {
"id": data.record.id,
"msg": "just for testing!"
};
$.ajax({
type: 'POST',
//contentType: 'application/json',
contentType: 'application/x-www-form-urlencoded',
headers: {
"XSRF-TOKEN": $('input:hidden[name="__RequestVerificationToken"]').val()
},
url: `?handler=DeleteBook`,
data: params
}).then(function () {
})
注意:
不能是 contentType: 'application/json', 而是取默认值: contentType: 'application/x-www-form-urlencoded'
如果 contentType: 'application/json',即
js调用
/Pages/Books/Index.jslet params = {
"id": data.record.id,
"msg": "just for testing!"
};
$.ajax({
type: 'POST',
contentType: 'application/json',
//contentType: 'application/x-www-form-urlencoded',
headers: {
"XSRF-TOKEN": $('input:hidden[name="__RequestVerificationToken"]').val()
},
url: `?handler=DeleteBook`,
data: JSON.stringify(params)
}).then(function () {
abp.notify.info(l('SuccessfullyDeleted'));
dataTable.ajax.reload();
})
其中,使用 contentType: 'application/json', data参数就得使用JSON.stringify(params)`将参数序列化
Razor Page 后台代码,得使用 [FromBody] 修饰参数
/Pages/Books/Index.cshtml.cspublic async TaskOnPostDeleteBookAsync([FromBody]DeleteBookViewModel vm)
{
await _bookAppService.DeleteAsync(vm.id);
return NoContent();
}
public class DeleteBookViewModel
{
public Guid id { get; set; }
public string msg { get; set; }
}
对象参数的写法是:[FromBody]DeleteBookViewModel vm