1. 正确的方式
javascript code:
var url = "some url";
var data = {"size": "width=8, height=9", "weight": "8 kg", "desc": "'&='"};
var string_data = (data);
$.ajax({
type: "POST",
url: url,
async: true,
data: {data: string_data},
success: function(response) {
alert("ok");
}
});
post时会自动URL编码,不用担心data中的特殊字符,firebug下可查看
data=%7B%22size%22%3A%22width%3D8%2C+height%3D9%22%2C%22weight%22%3A%228+kg%22%2C%22desc%22%3A%22'%26%3D'%22%7D
django view code:
def print_post_data(request):
data = ("data", None)
print "post data: %s" % (data, )
data = (data)
return HttpResponse("Success read post data.")
view代码能取出data的字符串形式,并且可以转成字典,不会被特殊字符干扰报错
2.错误的方式
对上例中的string_data做字符串拼接,如
string_data = "aaa=1&bbb=2&data=" + string_data + "&ccc=3";
或者
string_data = "aaa=1&bbb=2&data=‘" + string_data + "’&ccc=3";
然后js post代码不变(此时data : {data: string_data},整个string_data是一个对象的一个属性的值)
$.ajax({
type: "POST",
url: url,
async: true,
data: {data: string_data},
success: function(response) {
alert("ok");
}
});
这样不会报错,但是后端取出字符串 aaa=1&bbb=2&data={"size":"width=8, height=9","weight":"8 kg","desc":"'&='"}&ccc=3
难以抽取其中的字典和其他信息,几乎是无用。
如果这样post: data: {data: string_data} --------> data: string_data
$.ajax({
type: "POST",
url: url,
async: true,
data: string_data,
success: function(response) {
alert("ok");
}
});
django view取出的是被截断的字符串 {"size":"width=8, height=9","weight":"8 kg","desc":"'
并且由于引号截断,会报错
JSONDecodeError at /auth/print_post_data/
Unterminated string starting at: line 1 column 52 (char 51)
"aaa=1&bbb=2&data="这种QueryString格式字符串的存在,使Django采用QueryString解析方式解析整个post数据
关于这种方式导致的这个错误详细分析见/secretx/article/details/20398633
3.总结
对于post js object to django,应该注意两点,
第一,采用如下的方式post, data: {data: string_data}
$.ajax({
type: "POST",
url: url,
async: true,
data: {data: string_data},
success: function(response) {
alert("ok");
}
});
第二,string_data一定是一个js对象的字符串形式,也就是(jsObject)的结果,不要去拼接字符串。实在有拼接需求,也应该分两步,
先增加jsObject对象的属性,把要设置的值设置在属性里,如 jsObject.addItem1 = "item1"; jsObject.addItem2 = "item2";
然后string_data = (jsObject)。少用拼接字符串 ----改为--> 增加对象属性后