【发布时间】:2015-02-27 05:02:10
【问题描述】:
如有必要,我使用$(document).ajaxSend(...) 将数据(POST args)动态添加到某些 Ajax 请求中。
当$.ajax(...) 调用中定义了一些数据时,添加数据有效。但是如果$.ajax设置中没有定义数据,我的$.ajaxSend就无法在设置中添加数据。
这是我的$.ajaxSend拦截器:
$(document).ajaxSend(function(e, request, settings) {
if(settings.csrfIntention) {
var requestToken = {
intention: settings.csrfIntention,
hash: self.tokens[settings.csrfIntention]
}
if(!settings.data) {
settings.data = '_token=' + encodeURIComponent(JSON.stringify(requestToken));
}
else if(typeof(settings.data) == 'string') {
settings.data += '&_token=' + encodeURIComponent(JSON.stringify(requestToken));
}
else if(!settings.data._token) {
settings.data._token = requestToken;
}
}
});
还有一个有效的 $.ajax 调用示例:
$.ajax({
url: opts.close.url,
method: 'POST',
data: { foo:'bar' },
csrfIntention: 'ajax_close_ticket',
success: function(data) { ... }
});
$.ajaxSend 有效,settings.data 设置为:
foo=bar&_token=%7B%22intention%22%3A%22ajax_close_ticket%22%2C%22hash%22%3A%22uXV1AeZwm-bZL3KlYER-Dowzzd1QmCmaT6aJFjWLpLY%22%7D
服务器端,我可以检索两个字段:foo 和 _token。
现在,如果我在 $.ajax 调用中删除 data 对象,$.ajaxSend 的输出似乎也可以:
_token=%7B%22intention%22%3A%22ajax_close_ticket%22%2C%22hash%22%3A%225cK2WIegwI6u8K_FrxywuauWOo79xvhIcASQrZ9QPZQ%22%7D
但是,服务器没有收到我的 _token 字段:(
另一个有趣的事实:当我拥有这两个字段时,“网络”选项卡下的 Chromium 开发工具会在“表单数据”标题下显示这两个字段。单独使用 _token 时,“Form Data”替换为“Request Payload”。
编辑:刚刚明白为什么_token 不被服务器解释。如果之前在$.ajax 调用中没有设置数据,jQuery 不会在 HTTP 标头中添加正确的Content-Type,它会将其设置为text/plain 而不是application/x-www-form-urlencoded。如何强制 jQuery 添加此标头?
编辑 2: 找到解决方案。将发布答案以帮助其他人...
【问题讨论】:
标签: javascript jquery ajax