ajax
Posted zjsthunder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ajax相关的知识,希望对你有一定的参考价值。
向后台传输数据有两种方式1、form 提交后会刷新页面 2、ajax 提交数据后不会刷新页面
ajax是XMLHttPRequest对象。使用ajax分为3种情况,1、手动使用 2、jQuery方式使用 3、伪ajax
1、当遇到需求,不使用jQuery方式用ajax向后台发送数据。
<a href="#" onclick="func()">点击</a>
function func() {
var xhr = new XMLHttpRequest();//创建XMLHttpRequest对象
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
console.log(xhr.responseText);//xhr.responseText保存着服务端返回来的信息
}
};//以XMLHttpRequest对象向后台发送数据执行的回调函数,某些状态更改会触发执行。
//xhr.readyState取值有0-4
xhr.open("GET", "/ajax_2?p=123");
xhr.send(null);
}
def ajax_2(request):
print(request.POST)
print(request.GET)
return HttpResponse("ok")
后台没有对接收到的数据进行处理,只是打印接收到的数据。
上述代码的步骤为:1、创建 XMLHttpRequest对象,2、根据该对象设置回调函数,3、以什么方式,向哪个url创建连接,4、发送数据。回调函数中,xhr的状态改变就会触发回调函数的执行,其状态保存在xhr.readyState中,其详细的状态有
0——未初始化,尚未调用open方法
1——启动,调用了open()方法,还未调用send()方法。
2——发送,已经调用了send()方法,还未接收到响应。
3——接收,已经接收到部分响应数据。
4——完成,已经接收到全部响应数据。
发送get请求和post请求不一样,发送post请求需要设置发送的请求头。
request请求有请求头和请求体。数据发送是在request.body中,然后提取到request.GET;request.POST中,采用该方式发送数据时,请求头没有设置成Django能够识别的形式,因此需要将请求头设置成django能够识别的形式。
<a href="#" onclick="func_1()">点击</a>
function func_1() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
console.log(xhr.responseText);
}
};
xhr.open("POST", "/ajax_2/");
xhr.setRequestHeader(‘Content-Type‘, ‘application/x-www-form-urlencoded; charset-UTF-8‘)//设置请求头,Django中固定这种设置,还可以进行其他
//的设置,这样设置Django能够解析
xhr.send("p=456");
}
def ajax_2(request):
print(request.POST)
print(request.GET)
return HttpResponse("ok")
2、伪ajax
方法:采用iframe标签和form表单一起合用完成向后台发送数据而又不刷新页面。
该方法是兼容性最好的一种方式。
认识iframe:iframe有默认高度和宽度,在页面上显示类似于文本框textarea,有src属性,通过src属性发送请求,请求发送到后台,后台处理后将处理结果返回显示到iframe自己的内容区域中,外面的大的页面不刷新。
因此配合使用时需要做两点:2、在form表单上加上target="iframe标签的那么属性值"1、在iframe标签上加上name="名字"
<iframe name="ifra_a" onload="loadData(this)" id="ifra_2"></iframe> <form id="fm_a" action="/file_upload_1/" method="post" enctype="multipart/form-data" target="ifra_a"> <input type="file" name="test_file3" id="input_c" onchange="func_4()"> </form>
这样配合起来使用后,form提交到自己设定的路径的后台处理,后台处理后将处理的结果返回到iframe标签的内容区中。onchange表示输入框内容改变执行对应的函数。
回调函数,怎么取iframe标签中的值?
认识js中的this
1、在一个具体的标签中,this带指这一个标签。
在一个标签中有两种情况:1
<iframe name="ifra_a" onload="loadData(this)" id="ifra_2"></iframe>
2:
$("#ifra_2").click(function () {
$(this).html();
})
2、没有在一个具体的标签中,this带指window对象。
func_4()实现提交form表单,相当于input标签type = ‘submit‘的情况。
function func_4() {
document.getElementById("fm_a").submit()
}
上述实现了将输入的文件提交到后台,通过视图函数处理请求。
def fileUpload1(request):
testFile = request.FILES.get("test_file3")
file_path = os.path.join("static",testFile.name)
data = {"status":"ok","index":file_path}
f = open(file_path,"wb")
for line in testFile.chunks():
f.write(line)
f.close()
return HttpResponse(json.dumps(data))
回调函数:图片预览
function loadData(ths) {//当iframe中数据加载后执行onload对应的函数
var data = ths.contentWindow.document.body.innerHTML; //取得body中的字符串
var data_par = JSON.parse(data);//解析json字符串
var ele = document.createElement("img");
ele.src = "/"+data_par.index; //解析后的字典中的索引赋值给img对象的src属性
$("#preview").append(ele);
}
ajax的三种方式实现文件的上传
认识FormData()对象,可以看做一个特殊的字典,在其里面可以封装数据,包括文件,消息,相对于采用字典传输数据的方式,他的优势在于能够传输文件,而字典不行。
1、jQuery
<input type="file" name="test_file1" id="input_a"> <a onclick="submitajax()" href="#">上传</a>
function submitajax() {
var testdata = new FormData();
testdata.append("k",document.getElementById("input_a").files[0]);
$.ajax({
url:"/file_upload/",
type:"POST",
data:testdata,
success:function (arg) {
},
processData:false,//需要加上这两个参数,表示不对数据进行处理,就是不让jquery对数据处理
contentType:false,
})
}
2、原生XMLHttpR
<input type="file" id="input_file_c" onchange="submitajax_3()">
function submitajax_3() {
var data = new FormData();
data.append("k",document.getElementById("input_file_c").files[0]);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
};//回调函数
xhr.open("POST","/file_upload_3/");
//xhr.setRequestHeader(‘Content-Type‘, ‘application/x-www-form-urlencoded; charset-UTF-8‘);
xhr.send(data)
}
采用FormData对象提交数据和采用字典方式提交还有一点不同,不需要想后台提交请求头,字典方式组织的数据需要,不然request.POST上没有数据。jquery提交会自动处理数据会加上请求头,因此需要设置processData:false,
def fileUpload_3(request):
print(request.POST)
print(request.GET)
print(request.FILES)
testFile = request.FILES.get("k")
file_path = os.path.join("static",testFile.name)
data = {"status":"ok","index":file_path}
# print(testFile.name)
print(testFile.size)
f = open(file_path,"wb")
for line in testFile.chunks():
f.write(line)
f.close()
return HttpResponse(json.dumps(data))
3、iframe和from
<iframe style="display: none;" id="upload_iframe" name="upload_iframe"></iframe>
<form method="POST" action="/{{ username }}/upload-avatar/" enctype="multipart/form-data"
target="upload_iframe"id="upload_fm">
{% csrf_token %}
<img id="previewImg" src="/{{ user_obj.img }}"
style="border-radius: 50%;height: 70px;width: 70px"/>
<div class="text">点击图片更换(<a href="#">撤销</a>)</div>
<input id="avatarImg" name="avatar_img" type="file" class="img-file"onchange="submit_img()"/>
</form>
function submit_img() {
document.getElementById("upload_fm").submit();
}
Jsonp和跨域访问
浏览器都有同源策略;同源策略是浏览器最核心最基本的安全功能。同源是指,域名、协议、端口相同。
同源策略分为两种:
1、DOM同源策略
2、XMLHTTPRequest同源策略
不允许使用XHR对象向不同源的服务器地址发起HTTP请求
同源策略是为了浏览器上网的安全,但是由于有了同于策略,引起了跨域访问的问题。
JSONP跨域原理:
script标签不会受到同源策略的影响,动态创建script标签,利用src跨域。
<div id="div_jsonp_content"></div> <div href="" class="btn" onclick="func_jsonp()">点击</div>
function func_jsonp() {
var ele = document.createElement("script");
ele.src = "http://127.0.0.1:8000/jsonp-test/";//跨域访问,执行路径为下面一处贴的代码
document.head.appendChild(ele);
document.head.removeChild(ele);
}
function f_jsonp(arg) {
$("#div_jsonp_content").html(arg);
}
上述第一个函数1、先创建script标签,2、利用src跨域访问3、在head中添加标签4、移除标签
上述第二个函数,函数名和返回的字符串外层包裹相同,arg为内层字符串。
path(‘jsonp-test/‘, views.jsonp_test),//url需要跨域的服务器
def jsonp_test(request):
return HttpResponse("f_jsonp(‘jsonp_test‘)")
ajax有跨域访问的自动处理方式:对应的服务器返回同上。
<div href="" class="btn" onclick="func_jsonp1()">点击</div>
function func_jsonp1() {
$.ajax({
url:"http://127.0.0.1:8000/jsonp-test/",
type:"POST",
dataType:‘JSONP‘,
})
}
function f_jsonp(arg) {
{#$("#div_jsonp_content").html(arg);#}
console.log(arg)
}
ajax跨域指定返回的回调函数:
<div href="" class="btn" onclick="func_jsonp1()">点击</div>
function func_jsonp1() {
$.ajax({
url:"http://127.0.0.1:8000/jsonp-test/",
type:"GET",
dataType:‘JSONP‘,
jsonp:"callback",
jsonpCallback:"ffff",
})
}
function ffff(arg) {
{#$("#div_jsonp_content").html(arg);#}
console.log(arg)
}
服务器部分与先前有一些不同的地方
不同之处在视图处理函数,如下:
def jsonp_test(request):
name = request.GET.get("callback")
return HttpResponse("%s(‘jsonp_test‘)"%name)
以上是关于ajax的主要内容,如果未能解决你的问题,请参考以下文章