参考博客:http://www.cnblogs.com/wupeiqi/articles/5703697.html

提交:
- Form
- Ajax 一、Ajax,偷偷向后台发请求
- XMLHttpRequest
- 手动使用
- jQuery
- “伪”Ajax
- iframe标签
- form表单 二、Ajax上传文件
- jQuery
- 原生
以上两种方式可利用formData对象,来封装用户提交的数据 - Iframe+Form ******Iframe+Form******* 三、JSONP 跨域Ajax 浏览器同源策略:XMLHttpRequest
巧妙的机制JSONP JSONP:
利用创建script块,在期中执行src属性为:远程url
函数(返回值) function 函数(arg){ } 注意:CORS

一、概述

对于WEB应用程序:用户浏览器发送请求,服务器接收并处理请求,然后返回结果,往往返回就是字符串(HTML),浏览器将字符串(HTML)渲染并显示浏览器上。

1、传统的Web应用

一个简单操作需要重新加载全局数据

2、AJAX

AJAX,Asynchronous JavaScript and XML (异步的JavaScript和XML),一种创建交互式网页应用的网页开发技术方案。

  • 异步的JavaScript:
    使用 【JavaScript语言】 以及 相关【浏览器提供类库】 的功能向服务端发送请求,当服务端处理完请求之后,【自动执行某个JavaScript的回调函数】。
    PS:以上请求和响应的整个过程是【偷偷】进行的,页面上无任何感知。
  • XML
    XML是一种标记语言,是Ajax在和后台交互时传输数据的格式之一

利用AJAX可以做:
1、注册时,输入用户名自动检测用户是否已经存在。
2、登陆时,提示用户名密码错误
3、删除数据行时,将行ID发送到后台,后台在数据库中删除,数据库删除成功后,在页面DOM中将数据行也删除。(博客园)

二、原生AJAX和jQuery Ajax请求

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.btn {
display: inline-block;
padding: 5px 10px;
background-color: #2aabd2;
color: white;
}
</style>
</head>
<body> <h1>Ajax全套</h1>
<h3>1.Ajax发送GET请求</h3>
<div>
<a class="btn" onclick="AjaxSubmit1();">点我ajax</a>
<a class="btn" onclick="AjaxSubmit2();">点我XML</a>
</div>
<h3>2.Ajax发送POST请求</h3>
<div>
<a class="btn" onclick="AjaxSubmit3();">点我ajax</a>
<a class="btn" onclick="AjaxSubmit4();">点我XML</a>
</div> <script src="/static/js/jquery-3.3.1.js"></script>
<script>
function AjaxSubmit1() {
$.ajax({
url: "/ajax1",
type: "GET",
data: {'p':123, 'v':456},
success:function (arg) { }
})
} function AjaxSubmit2() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange=function () {
if (xhr.readyState == 4) {
// 接收完毕服务器返回的数据
console.log(xhr.responseText);
}
};
xhr.open('GET', '/ajax1?p=123');
xhr.send(null)
} function AjaxSubmit3() {
$.ajax({
url: "/ajax1/",
type: "POST",
data: {'p':123, 'v':456},
success:function (arg) { }
})
} function AjaxSubmit4() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange=function () {
if (xhr.readyState == 4) {
console.log(xhr.responseText);
}
};
xhr.open('POST', '/ajax1/');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
// 若不加setRequestHeader请求头,request.POST 拿不到数据,request.body 可以拿到数据
// 加上setRequestHeader请求头,request.POST request.body 都可以拿到数据
xhr.send('p=66666')
} </script> </body>
</html>

index.html

from django.shortcuts import render, redirect, HttpResponse

# Create your views here.

def index(request):
return render(request, 'index.html') def ajax1(request):
print(request.GET)
print(request.POST)
print(request.body) # if POST b'p=123&v=456' ;if GET b''
return HttpResponse('......')

views.py

"""Django_ajaxquantao URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path from app01 import views urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
path('ajax1/', views.ajax1)
]

urls.py

a.原生Ajax

主要就是使用 【XmlHttpRequest】对象来完成请求的操作,该对象在主流浏览器中均存在(除早起的IE),Ajax首次出现IE5.5中存在(ActiveX控件)。

1、XmlHttpRequest对象介绍

XmlHttpRequest对象的主要方法:

a. void open(String method,String url,Boolen async)
用于创建请求 参数:
method: 请求方式(字符串类型),如:POST、GET、DELETE...
url: 要请求的地址(字符串类型)
async: 是否异步(布尔类型) b. void send(String body)
用于发送请求 参数:
body: 要发送的数据(字符串类型) c. void setRequestHeader(String header,String value)
用于设置请求头 参数:
header: 请求头的key(字符串类型)
vlaue: 请求头的value(字符串类型) d. String getAllResponseHeaders()
获取所有响应头 返回值:
响应头数据(字符串类型) e. String getResponseHeader(String header)
获取响应头中指定header的值 参数:
header: 响应头的key(字符串类型) 返回值:
响应头中指定的header对应的值 f. void abort() 终止请求

XmlHttpRequest对象的主要属性:

a. Number readyState
状态值(整数) 详细:
0-未初始化,尚未调用open()方法;
1-启动,调用了open()方法,未调用send()方法;
2-发送,已经调用了send()方法,未接收到响应;
3-接收,已经接收到部分响应数据;
4-完成,已经接收到全部响应数据; b. Function onreadystatechange
当readyState的值改变时自动触发执行其对应的函数(回调函数) c. String responseText
服务器返回的数据(字符串类型) d. XmlDocument responseXML
服务器返回的数据(Xml对象) e. Number states
状态码(整数),如:200、404... f. String statesText
状态文本(字符串),如:OK、NotFound...

2、跨浏览器支持

    • XmlHttpRequest
      IE7+, Firefox, Chrome, Opera, etc.
    • ActiveXObject("Microsoft.XMLHTTP")
      IE6, IE5
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body> <h1>XMLHttpRequest - Ajax请求</h1>
<input type="button" onclick="XmlGetRequest();" value="Get发送请求" />
<input type="button" onclick="XmlPostRequest();" value="Post发送请求" /> <script src="/statics/jquery-1.12.4.js"></script>
<script type="text/javascript"> function GetXHR(){
var xhr = null;
if(XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
return xhr; } function XhrPostRequest(){
var xhr = GetXHR();
// 定义回调函数
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
// 已经接收到全部响应数据,执行以下操作
var data = xhr.responseText;
console.log(data);
}
};
// 指定连接方式和地址----文件方式
xhr.open('POST', "/test/", true);
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
// 发送请求
xhr.send('n1=1;n2=2;');
} function XhrGetRequest(){
var xhr = GetXHR();
// 定义回调函数
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
// 已经接收到全部响应数据,执行以下操作
var data = xhr.responseText;
console.log(data);
}
};
// 指定连接方式和地址----文件方式
xhr.open('get', "/test/", true);
// 发送请求
xhr.send();
} </script> </body>
</html>

基于原生Ajax

b.jQuery ajax

jQuery其实就是一个JavaScript的类库,其将复杂的功能做了上层封装,使得开发者可以在其基础上写更少的代码实现更多的功能。

  • jQuery 不是生产者,而是大自然搬运工。
  • jQuery Ajax本质 XMLHttpRequest 或 ActiveXObject

注:2.+版本不再支持IE9以下的浏览器

jQuery.get(...)
所有参数:
url: 待载入页面的URL地址
data: 待发送 Key/value 参数。
success: 载入成功时回调函数。
dataType: 返回内容格式,xml, json, script, text, html jQuery.post(...)
所有参数:
url: 待载入页面的URL地址
data: 待发送 Key/value 参数
success: 载入成功时回调函数
dataType: 返回内容格式,xml, json, script, text, html jQuery.getJSON(...)
所有参数:
url: 待载入页面的URL地址
data: 待发送 Key/value 参数。
success: 载入成功时回调函数。 jQuery.getScript(...)
所有参数:
url: 待载入页面的URL地址
data: 待发送 Key/value 参数。
success: 载入成功时回调函数。 jQuery.ajax(...) 部分参数: url:请求地址
type:请求方式,GET、POST(1.9.0之后用method)
headers:请求头
data:要发送的数据
contentType:即将发送信息至服务器的内容编码类型(默认: "application/x-www-form-urlencoded; charset=UTF-8")
async:是否异步
timeout:设置请求超时时间(毫秒) beforeSend:发送请求前执行的函数(全局)
complete:完成之后执行的回调函数(全局)
success:成功之后执行的回调函数(全局)
error:失败之后执行的回调函数(全局) accepts:通过请求头发送给服务器,告诉服务器当前客户端课接受的数据类型
dataType:将服务器端返回的数据转换成指定类型
"xml": 将服务器端返回的内容转换成xml格式
"text": 将服务器端返回的内容转换成普通文本格式
"html": 将服务器端返回的内容转换成普通文本格式,在插入DOM中时,如果包含JavaScript标签,则会尝试去执行。
"script": 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成普通文本格式
"json": 将服务器端返回的内容转换成相应的JavaScript对象
"jsonp": JSONP 格式
使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数 如果不指定,jQuery 将自动根据HTTP包MIME信息返回相应类型(an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string converters: 转换器,将服务器端的内容根据指定的dataType转换类型,并传值给success回调函数
$.ajax({
accepts: {
mycustomtype: 'application/x-some-custom-type'
}, // Expect a `mycustomtype` back from server
dataType: 'mycustomtype' // Instructions for how to deserialize a `mycustomtype`
converters: {
'text mycustomtype': function(result) {
// Do Stuff
return newresult;
}
},
});

jQuery Ajax方法列表

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body> <p>
<input type="button" onclick="XmlSendRequest();" value='Ajax请求' />
</p> <script type="text/javascript" src="jquery-1.12.4.js"></script>
<script> function JqSendRequest(){
$.ajax({
url: "http://c2.com:8000/test/",
type: 'GET',
dataType: 'text',
success: function(data, statusText, xmlHttpRequest){
console.log(data);
}
})
} </script>
</body>
</html>

jQuery ajax -demo

三、’伪‘Ajax

由于HTML标签的iframe标签具有局部加载内容的特性,所以可以使用其来伪造Ajax请求。

实例一

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.btn {
display: inline-block;
padding: 5px 10px;
background-color: #2aabd2;
color: white;
}
</style>
</head>
<body> <h1>Ajax全套</h1>
<h3>1.Ajax发送GET请求</h3>
<div>
<a class="btn" onclick="AjaxSubmit1();">点我ajax</a>
<a class="btn" onclick="AjaxSubmit2();">点我XML</a>
</div>
<h3>2.Ajax发送POST请求</h3>
<div>
<a class="btn" onclick="AjaxSubmit3();">点我ajax</a>
<a class="btn" onclick="AjaxSubmit4();">点我XML</a>
</div> <h3>3.伪ajax</h3>
<div>
<input type="text" id="url" placeholder="请输入URL" ><a href="#" onclick="test()">提交</a>
</div>
<iframe src="https://www.xiaohua.com/" frameborder="0" style="width: 800px;height: 600px" class="ifram"></iframe> <script src="/static/js/jquery-3.3.1.js"></script>
<script>
function AjaxSubmit1() {
$.ajax({
url: "/ajax1",
type: "GET",
data: {'p':123, 'v':456},
success:function (arg) { }
})
} function AjaxSubmit2() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange=function () {
if (xhr.readyState == 4) {
// 接收完毕服务器返回的数据
console.log(xhr.responseText);
}
};
xhr.open('GET', '/ajax1?p=123');
xhr.send(null)
} function AjaxSubmit3() {
$.ajax({
url: "/ajax1/",
type: "POST",
data: {'p':123, 'v':456},
success:function (arg) { }
})
} function AjaxSubmit4() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange=function () {
if (xhr.readyState == 4) {
console.log(xhr.responseText);
}
};
xhr.open('POST', '/ajax1/');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
// 若不加setRequestHeader请求头,request.POST 拿不到数据,request.body 可以拿到数据
// 加上setRequestHeader请求头,request.POST request.body 都可以拿到数据
xhr.send('p=66666')
} function test() {
var con = $('#url').val();
$('.ifram').attr('src',con);
} </script> </body>
</html>

html

实例二

基于Iframe+Form表单

    <iframe id="iframe" name="ifra"></iframe>
<form action="/ajax1/" id="fm" method="post" target="ifra">
<input type="text" name="root" value="1111">
<a onclick="AjaxSubmit5()">提交</a>
</form> <script>
function AjaxSubmit5() {
document.getElementById('fm').submit();
} </script>
    <iframe id="iframe" name="ifra"></iframe>
<form action="/ajax1/" id="fm" method="post" target="ifra">
<input type="text" name="root" value="1111">
<input type="submit" value="提交">
</form>
from django.shortcuts import render, redirect, HttpResponse

# Create your views here.

def index(request):
return render(request, 'index.html') def ajax1(request):
print(request.GET)
print(request.POST)
print(request.body) # if POST b'p=123&v=456' ;if GET b''
ret = {'status': 'OK', 'message': '......'}
import json
return HttpResponse(json.dumps(ret))

views.py

onload

    <iframe id="iframe" name="ifra" onload="reloadframe()"></iframe>
<form action="/ajax1/" id="fm" method="post" target="ifra">
<input type="text" name="root" value="1111">
<input type="submit" value="提交">
</form> <script> function reloadframe() {
console.log('abcdefg');
}
</script>
def ajax1(request):
import time
time.sleep(4)
print(request.GET)
print(request.POST)
print(request.body) # if POST b'p=123&v=456' ;if GET b''
ret = {'status': 'OK', 'message': '......'}
import json
return HttpResponse(json.dumps(ret))

伪ajax

iframe兼容性是最好的

    <iframe id="ifr" name="ifra"></iframe>
<form action="/ajax1/" id="fm" method="post" target="ifra">
<input name="root" value="1111">
<a href="#" onclick="AjaxSubmit5()">提交</a>
</form> function AjaxSubmit5() {
//$('#ifr').onload=ReloadFrame();
//$('#fm').submit();
document.getElementById('ifr').onload=ReloadFrame;
document.getElementById('fm').submit(); } function ReloadFrame() {
//console.log(this);
//console.log(this.contentWindow);
//console.log(this.contentWindow.document.body.innerHTML);
//console.log($(this).contents().find('body').html());
var content = this.contentWindow.document.body.innerHTML;
var obj = JSON.parse(content);
if(obj.status == "OK") {
alert(obj.message);
}
}
<!DOCTYPE html>
<html> <head lang="en">
<meta charset="UTF-8">
<title></title>
</head> <body> <div>
<p>请输入要加载的地址:<span id="currentTime"></span></p>
<p>
<input id="url" type="text" />
<input type="button" value="刷新" onclick="LoadPage();">
</p>
</div> <div>
<h3>加载页面位置:</h3>
<iframe id="iframePosition" style="width: 100%;height: 500px;"></iframe>
</div> <script type="text/javascript"> window.onload= function(){
var myDate = new Date();
document.getElementById('currentTime').innerText = myDate.getTime(); }; function LoadPage(){
var targetUrl = document.getElementById('url').value;
document.getElementById("iframePosition").src = targetUrl;
} </script> </body>
</html>

四、文件上传

利用FormData对象上传文件、字典

document.getElementById('img').files[0];得到上传的文件对象

ajax和原生ajax:
    <h3>上传文件</h3>
<input type="file" id="img">
<a class="btn" onclick="AjaxSubmit6();">上传</a>
<a class="btn" onclick="AjaxSubmit7()">上传</a> <script src="/static/js/jquery-3.3.1.js"></script>
<script>
function AjaxSubmit6() {
var data = new FormData();
data.append('k1','v1');
data.append('k2', 'v2');
data.append('k3', document.getElementById('img').files[0]);
$.ajax({
url: '/ajax1/',
type: 'POST',
data: data,
success:function (arg) {
console.log(arg);
},
processData: false,
contentType: false
})
} function AjaxSubmit7() { var data = new FormData();
data.append('k1','v1');
data.append('k2', 'v2');
data.append('k3', document.getElementById('img').files[0]); var xhr = new XMLHttpRequest();
xhr.onreadystatechange=function () {
if (xhr.readyState == 4) {
console.log(xhr.responseText);
}
};
xhr.open('POST', '/ajax1/');
//xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
xhr.send(data)
}
</script>

上传文件

form和iframe

    <iframe style="display: none" id="iframe1" name="ifra1"></iframe>
<form id="fm1" action="/ajax1.html" method="POST" enctype="multipart/form-data" target="ifra1">
<input type="text" name="k1" />
<input type="text" name="k2" />
<input type="file" name="k3" />
<a onclick="AjaxSubmit8()">提交</a>
</form>
function AjaxSubmit8() {
document.getElementById('iframe1').onload = reloadIframe1;
document.getElementById('fm1').submit();
}
function reloadIframe1() {
var content = this.contentWindow.document.body.innerHTML;
var obj = JSON.parse(content);
console.log(obj);
}

iframe上传文件

实例

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.btn{
display: inline-block;
padding: 5px 10px;
background-color: coral;
color: white;
}
</style>
</head>
<body>
<h1>Ajax全套</h1>
<h3>1.Ajax发送GET请求</h3>
<div>
<a class="btn" onclick="AjaxSubmit1();">点我</a>
<a class="btn" onclick="AjaxSubmit2();">点我</a>
</div>
<h3>2.Ajax发送POST请求</h3>
<div>
<a class="btn" onclick="AjaxSubmit3();">点我</a>
<a class="btn" onclick="AjaxSubmit4();">点我</a>
</div> <h3>3.莆田</h3>
<div> <h6>基于Iframe+Form表单</h6>
<iframe id="iframe" name="ifra"></iframe>
<form id="fm" action="/ajax1.html" method="POST" target="ifra">
<input name="root" value="111111" />
<a onclick="AjaxSubmit5()">提交</a>
</form> </div>
<h3>4.文件上传</h3>
<input type="file" id="img" />
<a class="btn" onclick="AjaxSubmit6();">上传</a>
<a class="btn" onclick="AjaxSubmit7();">上传</a> <iframe style="display: none" id="iframe1" name="ifra1"></iframe>
<form id="fm1" action="/ajax1.html" method="POST" enctype="multipart/form-data" target="ifra1">
<input type="text" name="k1" />
<input type="text" name="k2" />
<input type="file" name="k3" />
<a onclick="AjaxSubmit8()">提交</a>
</form> <script src="/static/js/jquery-3.1.1.js"></script>
<script> function AjaxSubmit1() {
$.ajax({
url: '/ajax1.html',
type:'GET',
data: {'p':123},
success:function (arg) { }
})
} function AjaxSubmit2() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
// 接收完毕服务器返回的数据
console.log(xhr.responseText); }
};
xhr.open('GET','/ajax1.html?p=123');
xhr.send(null);
} function AjaxSubmit3() {
$.ajax({
url: '/ajax1.html',
type:'POST',
data: {'p':123},
success:function (arg) { }
})
} function AjaxSubmit4() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
// 接收完毕服务器返回的数据
console.log(xhr.responseText); }
};
xhr.open('POST','/ajax1.html');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
xhr.send("p=456");
} function AjaxSubmit5() {
document.getElementById('iframe').onload = reloadIframe;
document.getElementById('fm').submit();
} function reloadIframe() {
// this=当前标签
//console.log(ths);
//console.log(ths.contentWindow);
//console.log(ths.contentWindow.document.body.innerHTML);
//console.log($(ths).contents().find('body').html());
var content = this.contentWindow.document.body.innerHTML;
var obj = JSON.parse(content);
if(obj.status){
alert(obj.message);
}
} function AjaxSubmit6() {
//document.getElementById('img')[0]
var data = new FormData();
data.append('k1','v1');
data.append('k2','v2');
data.append('k3',document.getElementById('img').files[0]); $.ajax({
url: '/ajax1.html',
type: 'POST',
data:data,
success:function (arg) {
console.log(arg)
},
processData: false, // tell jQuery not to process the data
contentType: false // tell jQuery not to set contentType })
} function AjaxSubmit7() {
var data = new FormData();
data.append('k1','v1');
data.append('k2','v2');
data.append('k3',document.getElementById('img').files[0]); var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
// 接收完毕服务器返回的数据
console.log(xhr.responseText); }
};
xhr.open('POST','/ajax1.html');
xhr.send(data);
} function AjaxSubmit8() {
document.getElementById('iframe1').onload = reloadIframe1;
document.getElementById('fm1').submit();
}
function reloadIframe1() {
var content = this.contentWindow.document.body.innerHTML;
var obj = JSON.parse(content);
console.log(obj);
}
</script>
</body>
</html>

Ajax全套

form和iframe文件预览

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.btn{
display: inline-block;
padding: 5px 10px;
background-color: coral;
color: white;
}
</style>
</head>
<body> <iframe style="display: none" id="iframe1" name="ifra1"></iframe>
<form id="fm1" action="/upload_img.html" method="POST" enctype="multipart/form-data" target="ifra1">
<input type="file" name="k3" onchange="uploadFile();" />
</form>
<h3>预览</h3>
<div id="preview">
</div>
<script src="/static/js/jquery-3.1.1.js"></script>
<script> function uploadFile() {
document.getElementById('iframe1').onload = reloadIframe1;
document.getElementById('fm1').submit();
}
function reloadIframe1() {
var content = this.contentWindow.document.body.innerHTML;
var obj = JSON.parse(content); var tag = document.createElement('img');
tag.src = obj.data;
$('#preview').empty().append(tag);
}
</script>
</body>
</html>

upload.html

def upload(request):
return render(request,'upload.html') def upload_img(request):
import os
import uuid
import json
nid = str(uuid.uuid4())
ret = {'status':True,'data':None,'message':None}
obj = request.FILES.get('k3') file_path = os.path.join('static', nid+obj.name)
f = open(file_path,'wb')
for line in obj.chunks():
f.write(line)
f.close()
ret['data'] = '/' + file_path
return HttpResponse(json.dumps(ret))

views.py

五、跨域AJAX

由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。

特别的:由于同源策略是浏览器的限制,所以请求的发送和响应是可以进行,只不过浏览器不接受罢了。

浏览器同源策略并不是对所有的请求均制约:

  • 制约: XmlHttpRequest
  • 不叼: img、iframe、script等具有src属性的标签

跨域,跨域名访问,如:http://www.c1.com 域名向 http://www.c2.com域名发送请求。

1、JSONP实现跨域请求

JSONP(JSONP - JSON with Padding是JSON的一种“使用模式”),利用script标签的src属性(浏览器允许script标签跨域) 

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title> </head>
<body> <div id="content"></div>
<input type="button" value="发送1" onclick="submitJsonp1();" />
<input type="button" value="发送2" onclick="submitJsonp2();" />
<input type="button" value="发送3" onclick="submitJsonp3();" />
<input type="button" value="发送4" onclick="submitJsonp4();" />
<script src="/static/js/jquery-3.3.1.js"></script>
<script>
function submitJsonp1() {
$.ajax({
url: '/ajax3.html',
type: 'GET',
data: {nid:2},
success:function (arg) {
$('#content').html(arg);
}
})
} function submitJsonp2() {
var tag = document.createElement('script');
tag.src = 'http://127.0.0.1:9000/xiaokai.html';
document.head.appendChild(tag);
document.head.removeChild(tag);
} function fuck(arg) {
$('#content').html(arg);
} function submitJsonp3() {
var tag = document.createElement('script');
tag.src = 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403';
document.head.appendChild(tag);
document.head.removeChild(tag);
} {# function list(arg) {#}
{# console.log(arg);#}
{# }#} function submitJsonp4() {
$.ajax({
url: 'http://127.0.0.1:9000/xiaokai.html',
type: 'POST',
dataType: 'jsonp',
jsonp: 'callback',
jsonpCallback: 'func'
})
}
function func(arg) {
console.log(arg);
}
</script>
</body>
</html>

jsonp.html


def jsonp(request):
return render(request,'jsonp.html') def ajax3(request):
return HttpResponse('本服务器发送的请求')

views.py

被请求端

from django.shortcuts import render, HttpResponse

# Create your views here.
def xiaokai(request):
# return HttpResponse('func("hello world")')
name = request.GET.get('callback')
return HttpResponse("%s('hello world....')"%name)

views.py

2、CORS

随着技术的发展,现在的浏览器可以支持主动设置从而允许跨域请求,即:跨域资源共享(CORS,Cross-Origin Resource Sharing),其本质是设置响应头,

使得浏览器允许跨域请求。

简单请求 OR 非简单请求


条件:
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

基于cors实现AJAX请求:

a、支持跨域,简单请求

服务器设置响应头:Access-Control-Allow-Origin = '域名' 或 '*'


<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body> <p>
<input type="submit" onclick="XmlSendRequest();" />
</p> <p>
<input type="submit" onclick="JqSendRequest();" />
</p> <script type="text/javascript" src="jquery-1.12.4.js"></script>
<script>
function XmlSendRequest(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
var result = xhr.responseText;
console.log(result);
}
};
xhr.open('GET', "http://c2.com:8000/test/", true);
xhr.send();
} function JqSendRequest(){
$.ajax({
url: "http://c2.com:8000/test/",
type: 'GET',
dataType: 'text',
success: function(data, statusText, xmlHttpRequest){
console.log(data);
}
})
} </script>
</body>
</html>

html


class MainHandler(tornado.web.RequestHandler):
def get(self):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.write('{"status": true, "data": "seven"}')

b、支持跨域,复杂请求

由于复杂请求时,首先会发送“预检”请求,如果“预检”成功,则发送真实数据。

  • “预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Request-Method
  • “预检”请求时,允许请求头则需服务器设置响应头:Access-Control-Request-Headers
  • “预检”缓存时间,服务器设置响应头:Access-Control-Max-Age

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body> <p>
<input type="submit" onclick="XmlSendRequest();" />
</p> <p>
<input type="submit" onclick="JqSendRequest();" />
</p> <script type="text/javascript" src="jquery-1.12.4.js"></script>
<script>
function XmlSendRequest(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
var result = xhr.responseText;
console.log(result);
}
};
xhr.open('PUT', "http://c2.com:8000/test/", true);
xhr.setRequestHeader('k1', 'v1');
xhr.send();
} function JqSendRequest(){
$.ajax({
url: "http://c2.com:8000/test/",
type: 'PUT',
dataType: 'text',
headers: {'k1': 'v1'},
success: function(data, statusText, xmlHttpRequest){
console.log(data);
}
})
} </script>
</body>
</html>

HTML


class MainHandler(tornado.web.RequestHandler):

    def put(self):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.write('{"status": true, "data": "seven"}') def options(self, *args, **kwargs):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.set_header('Access-Control-Allow-Headers', "k1,k2")
self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")
self.set_header('Access-Control-Max-Age', 10)

Tornado

c、跨域获取响应头

默认获取到的所有响应头只有基本信息,如果想要获取自定义的响应头,则需要再服务器端设置Access-Control-Expose-Headers。


<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body> <p>
<input type="submit" onclick="XmlSendRequest();" />
</p> <p>
<input type="submit" onclick="JqSendRequest();" />
</p> <script type="text/javascript" src="jquery-1.12.4.js"></script>
<script>
function XmlSendRequest(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
var result = xhr.responseText;
console.log(result);
// 获取响应头
console.log(xhr.getAllResponseHeaders());
}
};
xhr.open('PUT', "http://c2.com:8000/test/", true);
xhr.setRequestHeader('k1', 'v1');
xhr.send();
} function JqSendRequest(){
$.ajax({
url: "http://c2.com:8000/test/",
type: 'PUT',
dataType: 'text',
headers: {'k1': 'v1'},
success: function(data, statusText, xmlHttpRequest){
console.log(data);
// 获取响应头
console.log(xmlHttpRequest.getAllResponseHeaders());
}
})
} </script>
</body>
</html>

HTML


class MainHandler(tornado.web.RequestHandler):

    def put(self):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com") self.set_header('xxoo', "seven")
self.set_header('bili', "daobidao") self.set_header('Access-Control-Expose-Headers', "xxoo,bili") self.write('{"status": true, "data": "seven"}') def options(self, *args, **kwargs):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.set_header('Access-Control-Allow-Headers', "k1,k2")
self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")
self.set_header('Access-Control-Max-Age', 10)

Tornado

d、跨域传输cookie

在跨域请求中,默认情况下,HTTP Authentication信息,Cookie头以及用户的SSL证书无论在预检请求中或是在实际请求都是不会被发送。

如果想要发送:

  • 浏览器端:XMLHttpRequest的withCredentials为true
  • 服务器端:Access-Control-Allow-Credentials为true
  • 注意:服务器端响应的 Access-Control-Allow-Origin 不能是通配符 *
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body> <p>
<input type="submit" onclick="XmlSendRequest();" />
</p> <p>
<input type="submit" onclick="JqSendRequest();" />
</p> <script type="text/javascript" src="jquery-1.12.4.js"></script>
<script>
function XmlSendRequest(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
var result = xhr.responseText;
console.log(result);
}
}; xhr.withCredentials = true; xhr.open('PUT', "http://c2.com:8000/test/", true);
xhr.setRequestHeader('k1', 'v1');
xhr.send();
} function JqSendRequest(){
$.ajax({
url: "http://c2.com:8000/test/",
type: 'PUT',
dataType: 'text',
headers: {'k1': 'v1'},
xhrFields:{withCredentials: true},
success: function(data, statusText, xmlHttpRequest){
console.log(data);
}
})
} </script>
</body>
</html>

HTML

class MainHandler(tornado.web.RequestHandler):

    def put(self):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.set_header('Access-Control-Allow-Credentials', "true") self.set_header('xxoo', "seven")
self.set_header('bili', "daobidao")
self.set_header('Access-Control-Expose-Headers', "xxoo,bili") self.set_cookie('kkkkk', 'vvvvv'); self.write('{"status": true, "data": "seven"}') def options(self, *args, **kwargs):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.set_header('Access-Control-Allow-Headers', "k1,k2")
self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")
self.set_header('Access-Control-Max-Age', 10)

Tornado

Django(十九)Ajax全套的更多相关文章

  1. Python之路【第十九章】:Django进阶

    Django路由规则 1.基于正则的URL 在templates目录下创建index.html.detail.html文件 <!DOCTYPE html> <html lang=&q ...

  2. 第十九章 Django的ORM映射机制

    第十九章 Django的ORM映射机制 第一课 Django获取多个数据以及文件上传 1.获取多选的结果(checkbox,select/option)时: req.POST.getlist('fav ...

  3. 第三百八十九节,Django+Xadmin打造上线标准的在线教育平台—列表筛选结合分页

    第三百八十九节,Django+Xadmin打造上线标准的在线教育平台—列表筛选结合分页 根据用户的筛选条件来结合分页 实现原理就是,当用户点击一个筛选条件时,通过get请求方式传参将筛选的id或者值, ...

  4. 第三百七十九节,Django+Xadmin打造上线标准的在线教育平台—xadmin的安装

    第三百七十九节,Django+Xadmin打造上线标准的在线教育平台—xadmin的安装 xadmin介绍 xadmin是基于Django的admin开发的更完善的后台管理系统,页面基于Bootstr ...

  5. 第三百六十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索功能

    第三百六十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索功能 Django实现搜索功能 1.在Django配置搜索结果页的路由映 ...

  6. 第三百一十九节,Django框架,文件上传

    第三百一十九节,Django框架,文件上传 1.自定义上传[推荐] 请求对象.FILES.get()获取上传文件的对象上传对象.name获取上传文件名称上传对象.chunks()获取上传数据包,字节码 ...

  7. Python之路【第十九篇】:爬虫

    Python之路[第十九篇]:爬虫   网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用 ...

  8. Django框架之Ajax和form组件

    一.Django框架之查漏补缺 1)models,字段概况 name = models.CharField(max_length=) age = models.IntegerField() price ...

  9. Python开发之AJAX全套

    概述 对于WEB应用程序:用户浏览器发送请求,服务器接收并处理请求,然后返回结果,往往返回就是字符串(HTML),浏览器将字符串(HTML)渲染并显示浏览器上. 1.传统的Web应用 一个简单操作需要 ...

随机推荐

  1. python[练习题]:实现Base64编码

    要求自己实现算法,不用库. Base64简介: Base64是一种用64个字符来表示任意二进制数据的方法. 用记事本打开exe.jpg.pdf这些文件时,我们都会看到一大堆乱码,因为二进制文件包含很多 ...

  2. 集合转数组的toArray()和toArray(T[] a)方法

    参考:集合转数组的toArray()和toArray(T[] a)方法 1.ArrayList的toArray ArrayList提供了一个将List转为数组的一个非常方便的方法toArray.toA ...

  3. Java对象clone()的测试

    Object中自带native clone()方法. 研究了一下用法. public class DeepCopyTest { public static void main(String[] arg ...

  4. Uninstall registry

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

  5. How to flash Havoc on enchilada

    update fastboot and adb fastboot oem unlock adb debug enchilada reboot to fastboot fastboot devices ...

  6. 4.namespace

    命名空间( namespace)是 Linux 内核的一个强大特性,为容器虚拟化的实现带来极大便 利. 利用这一特性,每个容器都可以拥有自己单独的命名空间,运行在其中的应用都像是在 独立的操作系统环境 ...

  7. k8s(一) kubeadm简单集群初始化

    写给想入门kubernetes的同学们 # 系统版本 [root@master ~]# cat /etc/os-release NAME="CentOS Linux" VERSIO ...

  8. Asp.Net Core 输出 Word

    In one of the ASP.NET Core projects we did in the last year, we created an OutputFormatter to provid ...

  9. spring的作用是减低耦合,从编译器降低,例如不直接通过new方式 而是通过工厂方式获取对象

    spring的作用是减低耦合,从编译器降低,例如不直接通过new方式 而是通过工厂方式获取对象

  10. python源码编译

    PyInstaller是一个基于windows平台,将源码打包成执行文件的第三方库,PyInstaller本身并不属于Python包. 源文件要采用UTF-8编码 安装Pyinstaller pip ...