参考资料:
- https://www.cnblogs.com/zhao123/p/11765642.html
- https://www.learnrazorpages.com/security/request-verification#ajax-post-requests
- https://blog.csdn.net/weixin_30674525/article/details/99174807
GET 请求
Razor Page 后台代码:
/Pages/Books/Index.cshtml.cs
public async Task<ActionResult> OnGetBookListAsync()
{
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
中的BookList
即:后台方法:OnGetXyzAsync()
, 则 url:?handler=Xyz
POST请求
发起post请求时,Asp.Net Core 为了防止 XSS
h和 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 Task<ActionResult> OnPostDeleteBookAsync(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 () {
})
注意:
-
url的规则是:?handler= 加上
OnPostDeleteBookAsync
中的BookList
即:后台方法:OnPostXyzAsync()
, 则 url:?handler=Xyz -
解决Asp.Net Core 为了防止
XSS
h和CSRF
引发的网站安全问题, js 直接问后台代码是会报错的问题:
headers: {
"XSRF-TOKEN": $('input:hidden[name="__RequestVerificationToken"]').val()
},
-
不能是 contentType: 'application/json', 而是取默认值: contentType: 'application/x-www-form-urlencoded'
-
Asp.net Core框架能自动类型转换
后台方法:
public async Task<ActionResult> OnPostDeleteBookAsync(string id) {....}
id 的类型也可以是Guid
public async Task<ActionResult> OnPostDeleteBookAsync(Guid id)
,前端js传id时值为string,Asp.net Core框架能自动转化为Guid
类型
POST对象参数
有时,POST请求参数是一个对象,
Razor Page 后台代码:
/Pages/Books/Index.cshtml.cs
public async Task<ActionResult> OnPostDeleteBookAsync(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.js
let 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.js
let 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.cs
public async Task<ActionResult> OnPostDeleteBookAsync([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