5 jquery xmlhttprequest http-post asp.net-mvc-5
我正在使用一个名为Slim 的库将图像上传到我的 asp.net MVC 项目。
JQuery 库使用 XMLHttpRequest 向服务器发送请求,我已经阅读了所有手册,但没有任何关于如何将防伪造令牌包含到服务器的内容。
所以我在发送之前手动添加了这一行:
data.__RequestVerificationToken = $('input[name="__RequestVerificationToken"]').val();
Run Code Online (Sandbox Code Playgroud)
即使令牌包含在数据中,Asp.net MVC 过滤器:ValidateJsonAntiForgeryTokenAttribute也无法识别它,因为它期望令牌位于 header中。这是服务器上的验证代码:
AntiForgery.Validate(cookie != null ? cookie.Value : null,
httpContext.Request.Headers["__RequestVerificationToken"]);
Run Code Online (Sandbox Code Playgroud)
这是库的发送函数,其中包含我在底部添加的额外行以包含令牌。如何将令牌包含在标头中?
var send = function send(url, data, requestDecorator, progress, success, err) {
var xhr = new XMLHttpRequest();
// if progress callback defined handle progress events
if (progress) {
xhr.upload.addEventListener('progress', function (e) {
progress(e.loaded, e.total);
});
}
// open the request
xhr.open('POST', url, true);
// if request decorator defined pass XMLHttpRequest instance to decorator
if (requestDecorator) {
requestDecorator(xhr);
}
// handle state changes
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 300) {
var text = xhr.responseText;
// if no data returned from server assume success
if (!text.length) {
success();
return;
}
// catch possible PHP content length problem
if (text.indexOf('Content-Length') !== -1) {
err('file-too-big');
return;
}
// if data returned it should be in suggested JSON format
var obj = void 0;
try {
obj = JSON.parse(xhr.responseText);
} catch (e) {}
// if is failure response
if ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && obj.status === 'failure') {
err(obj.message);
return;
}
success(obj || text);
} else if (xhr.readyState === 4) {
var _obj = void 0;
try {
_obj = JSON.parse(xhr.responseText);
} catch (e) {}
// if is clean failure response
if ((typeof _obj === 'undefined' ? 'undefined' : _typeof(_obj)) === 'object' && _obj.status === 'failure') {
err(_obj.message);
return;
}
err('fail');
}
};
// I have added this line to library to include anti forgery token
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
data.__RequestVerificationToken = $('input[name="__RequestVerificationToken"]').val();
// do request
xhr.send(data);
Run Code Online (Sandbox Code Playgroud)
}; `
您需要在标头中设置 antiforgerytoken,如下所示:
xhr.setRequestHeader('__RequestVerificationToken', $('input[name="__RequestVerificationToken"]').val());
Run Code Online (Sandbox Code Playgroud)
有关 XMLHttpRequest 的更多信息,请参阅XMLHttpRequest.setRequestHeader :
要验证标头中传递的 AntiforgeryToken,在控制器中,您需要创建自己的过滤器,如下所示:
[HttpPost]
[ValidateJsonAntiForgeryToken]
public ActionResult MySlimAction()
{
/* your Save controller logic goes here */
}
Run Code Online (Sandbox Code Playgroud)
将此过滤器定义作为新类添加到您的 Filters 文件夹中:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class ValidateJsonAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
var httpContext = filterContext.HttpContext;
var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName];
AntiForgery.Validate(cookie != null ? cookie.Value : null,
httpContext.Request.Headers["__RequestVerificationToken"]);
}
}
Run Code Online (Sandbox Code Playgroud)
对于您的特定库Slim Image Cropper,您可以在初始化 Slim 时使用willRequest回调:
var cropper = $('#my-cropper-selector').slim({
willRequest: function (xhr) {
xhr.setRequestHeader('__RequestVerificationToken', $('input[name="__RequestVerificationToken"]').val());
},
ratio: 'free',
push: true,
service: '/MyController/MySlimAction'
/* other options go here */
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2654 次 |
| 最近记录: |