网上看到许多Ajax传递中文字符的解决方法,但都是比较高级的方法。我看不懂啊,觉得好复杂。翻了好多前辈的网页,找到一个解决方案。我这里用比较直白的语言解答一下,让像我这样的小白不必看到别人的解答方法就懵圈。
先上HTML页面的代码:
function type_item_change_js(id){
var xmlhttp;
if (window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
var str = xmlhttp.responseText;
if( str == "Noprivilege" )
{
alert("您没有操作权限");
}
else{
var indextmp = id.indexOf("_");
var item_id = "item"+id.slice(indextmp);
document.getElementById(item_id).innerHTML=xmlhttp.responseText;
}
}
}
var rand_value=Math.random();
var url = "/weekdays_plan/type_item_change_js/?workday_id="+id+"&value="+rand_value ;
xmlhttp.open("GET",encodeURI(encodeURI(url)),true);
xmlhttp.send();
}
解释一下这段ajax代码要干嘛。我这个Html页面点击一个按钮后,会将类似“课目1:体育训练_12_1”这样格式的字符串作为id的值传递给json函数type_item_change_js。
这里再通俗一点解释,因为怕有些像我一样的小白还是懵圈。就是说,我在该HTML页面定义了一个json函数type_item_change_js(id)。我给id传递的字符串样式是类似“课目1:体育训练_12_1”这样的字符串。
Django的views.py中视图函数是这样的:
from urllib.parse import unquote
def type_item_change_js(request):
id_str = unquote(request.GET.get("workday_id"),"UTF-8")
workday_id = id_str[id_str.find("_")+1:-2]
item_field = f"train_type{id_str[-1]}_item"
item_str = id_str[:id_str.find("_")]
workday = Workdays.objects.get(id=workday_id)
setattr(workday, item_field, item_str)
workday.save()
return HttpResponse(item_str)
这是成功解码中文字符的视图函数。如果你是使用:
id_str = request.GET.get("workday_id")
此时你得到的id_str字符串是不能正确显示中文的,而是%E8%AF%BE%E7%9B%AE1:%E4%BD%93%E8%82%B2%E8%AE%AD%E7%BB%83_12_1
这样的乱码。所以,你必须得使用unquote()函数进行解码,使用这个函数必须得导入模块:
from urllib.parse import unquote
总结来说,你想使用Ajax传递中文给Django的视图函数使用,那么就如下操作:
1、创建url变量,比如:
var url = "/weekdays_plan/type_item_change_js/?workday_id="+id+"&value="+rand_value ;
2、xmlhttp.open()函数的url参数值,用encodeURI(encodeURI(url))对你创建的url变量进行两次编码。注意,encodeURI最后一个字母是i(爱),不是L。你创建的url变量最后一个字符是i还是L,无所谓,只是一个变量名称而已。
后来我测试了一下,发现只编码一次也可以。但是看了别人的一个网页,说编码两次,具体原因也没详细了解,我看成功了也就没有详细根究。
3、视图函数中导入unquote函数。
from urllib.parse import unquote
4、使用unquote()函数解码request中的workday_id字符串就可以了。
补充解释一下:为什么我的url中要加一个随机值rand_value。有些跟我一样的小白,可能没遇到过类似的困扰。加入随机数的目的,是为了让每次点击按钮时,触发Ajax函数传递给open()函数的url值都不一样。因为如果每次都一样的话,你会发现,你第二次点击按钮后,Ajax函数没有起作用。