jQuery .ajaxSend:无法动态添加数据

时间:2015-02-26 20:28:23

标签: javascript jquery ajax

我在必要时使用$(document).ajaxSend(...)动态地向某些Ajax请求添加数据(POST args)。 在$.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

Serverside,我可以检索两个字段:foo和_token。

现在,如果我删除data调用中的$.ajax对象,$.ajaxSend的输出似乎也可以:

 _token=%7B%22intention%22%3A%22ajax_close_ticket%22%2C%22hash%22%3A%225cK2WIegwI6u8K_FrxywuauWOo79xvhIcASQrZ9QPZQ%22%7D

然而,服务器没有收到我的_token字段:(

另一个有趣的事实:当我有两个字段时,网络选项卡下的Chromium开发工具会在"表格数据"下显示两个字段。标题。当_token独自时,"表单数据"被"请求有效负载"。

取代

编辑:只是理解为什么服务器不会解释_token。如果之前未在$.ajax调用中设置任何数据,则jQuery不会在HTTP标头中添加正确的Content-Type,而是将其设置为text/plain而不是application/x-www-form-urlencoded。如何强制jQuery添加此标头?

修改2:找到解决方案。会发一个答案来帮助其他人......

3 个答案:

答案 0 :(得分:0)

我为我糟糕的英语道歉

我相信他的案例的解决方案是使用函数" ajaxSetup"

var requestToken = {
        intention: settings.csrfIntention,
        hash: self.tokens[settings.csrfIntention]
};

$.ajaxSetup({
    data : {
        _token: requestToken
    }
});

这样你所有的订单都将数据作为愿望

答案 1 :(得分:0)

更简单的方法:

var requestToken = {
        intention: settings.csrfIntention,
        hash: self.tokens[settings.csrfIntention]
    }
var myForm = {};
myForm['_token'] = encodeURIComponent(JSON.stringify(requestToken));

在你的ajax电话中:

myForm['foo'] = 'bar';
$.ajax({
    url: opts.close.url,
    method: 'POST',
    data: myForm,
    csrfIntention: 'ajax_close_ticket',
    success: function(data) { ... }
});
//This sends foo and _token

答案 2 :(得分:0)

最后我在10分钟后回答我的问题......

在HTTP中,表单参数被发送到标题下的请求正文中。标题Content-Type应该存在以声明数据类型。当此标头设置为application/x-www-form-urlencoded时,服务器将了解您已发送表单并将请求正文解析为GET URL(您知道,foo=bar&key=val格式)。

当您将data对象设置为$.ajax调用时,jQuery会自动添加此标头。然后它将请求传递给$.ajaxSend回调,后者会添加正确的字段。

如果请求设置中未提供data,则jQuery不会在请求标头中添加不必要的Content-Type: x-www-form-urlencoded。然后,当您将请求主体附加到$.ajaxSend回调中时,jQuery不会再次检查数据并将内容声明为text/plain。服务器与text/plain无关,因此它不会将正文数据解释为表单字段。

您显然可以强制jQuery将标题更改为application/x-www-form-urlencoded,让我们采用原始帖子的代码:

if(!settings.data) {
    settings.data = '_token=' + encodeURIComponent(JSON.stringify(requestToken));
}

现在添加正确的标题:

if(!settings.data) {
    settings.data = '_token=' + encodeURIComponent(JSON.stringify(requestToken));
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}