AJAX简介
AJAX(Asynchronous Javascript And XML) 相当于异步JavaScript和XML
AJAX是一种用于创建快速动态网页的技术
原理是在后台与服务器进行少量的数据交换,AJAX可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
特点:可以在用户不知不觉的情况下实现网页局部刷新。
js实现局部刷新
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="jquery-3.2.1.js"></script>
<style>
.error{
color: red;
}
</style>
</head>
<body>
<form class="Form">
<p>用户名:<input type="text" class="v1"name="username" mark="用户名"></p>
<p><input type="text" class="v1"name="email" mark="邮箱"></p>
<p><input type="submit" value="提交"></p>
</form>
<script>
$('.Form :submit').click(function () {
flag=true;
$('Form .v1').each(function () {
var value=$(this).val();
if (value.trim().length==0){
var mark=$(this).attr('mark');
var $span = $('<span>');
$span.html(mark+'不能为空!');
$span.prop('class','error');
$(this).after($span);
setTimeout(function () {
$span.remove();
},800);
flag=false;
return flag
}
});
return flag
})
</script>
</body>
</html>
AJAX优缺点
优点:
AJAX使用JavaScript技术向服务器发送异步请求
AJAX无需刷新整个页面
服务器相应内容不再是整个页面,而是页面中的局部,所以AJAX性能更高
JQuery实现AJAX
Ajax get/post请求
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/static/jquery3.2.1.js"></script>
</head>
<body>
<p><input type="text" class="a1"> + <input type="text" class="a2"> = <input type="text" class="a3"></p>
<button class="ss">提交</button>
<script>
$('.ss').click(function () {
$.ajax({
url: '/ajax2/', //URL对应相应的视图函数
type: 'GET', //请求方式,大小写都行
data: {
valueA:$('.a1').val(),
valueB:$('.a2').val(),
csrfmiddlewaretoken: '{{ csrf_token }}' //post提交数据要加上这个键值对
},
success: function (data) { //回调函数
var data = JSON.parse(data);
$('.a3').val(data)
}
})
});
/*$('.ss').click(function () {
$.ajax({
url:'/ajax2/',
type:'GET',
data:{
valueA:$('.a1').val(),
valueB:$('.a2').val()
},
success:function (data) {
var data = JSON.parse(data);
$('.a3').val(data)
}
})
}) */
</script>
</body>
</html>
views.py
from django.shortcuts import render,HttpResponse
# Create your views here.
def index(request):
return render(request,'index.html')
def ajax2(request):
a = request.GET.get('valueA')
b = request.GET.get('valueB')
res = int(a) + int(b)
return HttpResponse(res)
ajax实现用户登录
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/static/jquery-3.2.1.js"></script>
<style>
.error_msg{
color: red;
}
</style>
</head>
<body>
<h1>Ajax实现登录</h1>
<form action="" novalidate>
{% csrf_token %}
<p><input type="text"></p>
<p><input type="password"></p>
</form>
<button class="send_ajax">Ajax提交</button> <span class="error_msg"></span>
<script>
function foo() {
$('.error_msg').html('')
}
$('.send_ajax').click(function () {
$.ajax({
url:'/process/',
type:'post',
data:{
csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val(),
name:$(':text').val(),
pwd:$(':password').val()
},
success:function (data) {
var data = JSON.parse(data);
if (!data['flag']){
$('.error_msg').html('Username Or Password error!')
setTimeout(foo,3000)
}
else{
alert('Login success!')
}
}
})
})
</script>
</body>
</html>
views.py
def processing(request):
username = request.POST.get('name')
password = request.POST.get('pwd')
response = {'flag':False}
if username == 'parker' and password == '123':
response['flag'] = True
return HttpResponse(json.dumps(response))
请求参数
data:
当前AJAX请求要携带的数据,是一个json的object对象,AJAX方法就会默认把他编码成某种格式(urlencoded:?a=1&b=2)发送给服务端;AJAX默认以get方式发送请求
processData
声明当前的data数据是否进行转码或者预处理。默认为true,即预处理;
contentType
默认值:'application/x-www-form-urlencoded' 发送信息至服务端的编码类型。用来指明当前请求的数据编码格式;urlencoded:?a=1&b=2;如果以其他方式提交数据,比如contentType:'applicaiton/json',即向服务器发送一个json字符串
CSRF跨站请求伪造
方式一
$.ajaxSetup({
data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});
方式二
<form>
{% csrf_token %}
</form><br><br><br>$.ajax({<br>...<br>data:{
"csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val();
1
}<br>})
方式三
<script src="{% static 'js/jquery.cookie.js' %}"></script>
$.ajax({
headers:{"X-CSRFToken":$.cookie('csrftoken')},
}) // 需要导入jquery.cookie.js文件
JS实现的ajax
AJAX核心(XMLHttpRequest)
其实AJAX就是在JavaScript中多添加了一个对象:XMLHttpRequest对象。
所有异步交互都是通过XMLHttpServlet对象完成的。
var xmlHttp = new XMLHttpRequest();
上传文件
Form表单上传文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>form表单上传文件</h3>
<form action="/upload_file/" method="post" enctype="multipart/form-data"> <!--注意 enctype设置 -->
{% csrf_token %}
<p><input type="file" name="upload_file_form"></p>
<input type="submit" value="提交">
</form>
</body>
</html>
Ajax(FormData)上传文件
XMLHttpRequest Level 2添加了一个新的接口FormData.利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()方法来异步的提交这个"表单".比起普通的ajax,使用FormData的最大优点就是我们可以异步上传一个二进制文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/static/jquery-3.2.1.js"></script>
<style>
.error_msg{
color: red;
}
</style>
</head>
<body>
<h1>Ajax实现登录上传文件</h1>
<form action="" novalidate>
{% csrf_token %}
<p><input type="text"></p>
<p><input type="password"></p>
<input type="file" id="upload_file">
</form>
<button class="send_ajax">Ajax提交</button> <span class="error_msg"></span>
<script>
function foo() {
$('.error_msg').html('')
}
$('.send_ajax').click(function () {
var formData = new FormData(); //实例化一个FormData()对象
formData.append('name',$(":text").val());
formData.append('pwd',$(':password').val());
formData.append('file_obj',$('#upload_file')[0].files[0]); //添加文件对象到FormData对象中
formData.append('csrfmiddlewaretoken',$("[name='csrfmiddlewaretoken']").val());
$.ajax({
url:'/process2/',
type:'post',
data:formData,
contentType:false, //FormData上传文件,必须加上contentType和processData
processData:false,
//headers:{"X-CSRFToken":$.cookie('csrftoken')},
success:function (data) {
var data = JSON.parse(data);
if (!data['flag']){
$('.error_msg').html('Username Or Password error!');
setTimeout(foo,3000)
}
else{
alert('Login success!')
}
}
})
})
</script>
</body>
</html>
同源策略与JSONP
同源策略
同源策略(same origin policy)它是由Netspace提出的一个著名的安全策略,现在所有支持JavaScript的浏览器都会使用这个策略。所谓同源是指,域名,端口,协议都相同。
JSONP原理:利用script标签的src属性绕过同源策略。
特别的:由于同源策略是浏览器的限制,所以请求的发送和响应可以进行,只不过浏览器不接受罢了。
浏览器同源策略并不是对所有的请求都制约:
制约:XMLHTTPRequest
不制约:img、iframe、script等具有src属性的标签
JSONP实现跨域请求
利用js实现
function func(arg) {
alert(arg);
document.head.removeChild(tag)
}
function Jsonp(url) {
var tag = document.createElement('script'); //动态生成script标签
tag.src = url;
document.head.appendChild(tag)
}
def get_details(request):
return HttpResponse('func("Confidential Information")') # 远程调用回调函数
利用jQuery实现
index.html
本地先定义函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>index</h1>
<input type="button" onclick="Jsonp('http://127.0.0.1:8888/details/?callback=func')" value="JsonP发送数据">
<script src="/static/jquery-3.2.1.js"></script>
<script>
function func(arg) {
alert(arg)
}
$.ajax({
url:'http://127.0.0.1:8888/details/',
type:'get',
dataType:'JSONP',
jsonp:'callback',
jsonpCallback:'func'
})
/*function Jsonp(url) {
var tag = document.createElement('script');
tag.src = url;
document.head.appendChild(tag)
}*/
/*$.ajax({
url:'http://127.0.0.1:8888/details/',
type:'get',
success:function (arg) {
console.log(arg)
}
})*/
</script>
</body>
</html>
远程,调用回调函数
def get_details(request):
func_name_str = request.GET.get('callback')
return HttpResponse('%s("confidential details here..........")'%func_name_str)
总结:
JSOP(是Json的一种使用模式),利用script标签的src属性(浏览器允许script标签跨域。)
*********************************8
jsonp: 'callbacks'就是定义一个存放回调函数的键,jsonpCallback是前端定义好的回调函数方法名'SayHi',server端接受callback键对应值后就可以在其中填充数据打包返回了;
jsonpCallback参数可以不定义,jquery会自动定义一个随机名发过去,那前端就得用回调函数来处理对应数据了。利用jQuery可以很方便的实现JSONP来进行跨域访问。
注意: JSONP一定是GET请求
CORS解决跨域问题
CORS(Cross-Origin Resource Sharing)跨域资源共享,本质是设置响应头,使得浏览器允许跨域请求。
简单请求和复杂请求
条件:
1、请求方式:HEAD、GET、POST
2、请求头信息:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type 对应的值是以下三个中的任意一个
application/x-www-form-urlencoded
multipart/form-data
text/plain
注意:同时满足以上两个条件时,则是简单请求,否则为复杂请求
二者区别:
简单请求:一次请求
非简单请求:两次请求,在发送数据之前会先发一次请求用于做“预检”,只有“预检”通过后才再发送一次请求用于数据传输。
关于预检
请求方式:OPTIONS
- “预检”其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息
- 如何“预检”
=> 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过
Access-Control-Request-Method
=> 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过
Access-Control-Request-Headers
网友评论