Json+Ajax相关
Ajax前戏之json:
1、什么是json?
JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。
2、json对象和JavaScript对象的关系
json对象:JavaScript对象的子集,json继承了JavaScript的number,string(" "),bool,null,array,{"name":"egon" ,"age ":18} 注意json只支持双引号 ;
3、json对象和json字符串的关系:
json字符串就是json对象+引号的字符串化,‘json对象 ’,json对象=JS对象,json字符串‘ 里面’存储的JavaScript的数据类型,所以相比其他语言JavaScript把json字符串解析成JS对象有天然优势;
3、json字符串和Python的关系
Python有Python的数据类型,JS有JS的数据类型,但前后端之所以可以交互,是因为中间有 json字符串做中间转换;
合格的json对象:
["one", "two", "three"] { "one": 1, "two": 2, "three": 3 } {"names": ["张三", "李四"] } [ { "name": "张三"}, {"name": "李四"} ]
不合格的json对象
{ name: "张三", 'age': 32 } // 属性名必须使用双引号 [32, 64, 128, 0xFFF] // 不能使用十六进制值 { "name": "张三", "age": undefined } // 不能使用undefined { "name": "张三",
"birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'),
"getName": function() {return this.name;} // 不能使用函数和日期对象
}
4、JavaScript的JSON.stringify()和JSON.stringify()方法
JSON.stringify(JS对象) 将JS对象序列化成 JSON字符串 ------->python的json.dumps()
<script>
{#JSON.stringify(JS对象) 将JS对象序列化成 JSON字符串#}
console.log(typeof JSON.stringify([1,2,2,2]))
console.log(typeof JSON.stringify({'name':'egon'}))
</script>
JSON.parse('JSON对象') 将json字符串反序列化成 JS对象--------->python的json.loads()
<script>
{# JSON.parse('JSON对象') 将json字符串反序列化成 JS对象 #}
console.log(JSON.parse('{"name":"egon","age":18}'))
console.log(JSON.parse('[1,2,3,4,5]'))
</script>
5、json和XML的比较
JSON 格式于2001年由 Douglas Crockford 提出,目的就是取代繁琐笨重的 XML数据交换格式。
用XML表示中国部分省市数据如下:
<?xml version="1.0" encoding="utf-8"?>
<country>
<name>中国</name>
<province>
<name>黑龙江</name>
<cities>
<city>哈尔滨</city>
<city>大庆</city>
</cities>
</province>
<province>
<name>广东</name>
<cities>
<city>广州</city>
<city>深圳</city>
<city>珠海</city>
</cities>
</province>
<province>
<name>台湾</name>
<cities>
<city>台北</city>
<city>高雄</city>
</cities>
</province>
<province>
<name>新疆</name>
<cities>
<city>乌鲁木齐</city>
</cities>
</province>
</country>
用JSON表示如下:
{
"name": "中国",
"province": [{
"name": "黑龙江",
"cities": {
"city": ["哈尔滨", "大庆"]
}
}, {
"name": "广东",
"cities": {
"city": ["广州", "深圳", "珠海"]
}
}, {
"name": "台湾",
"cities": {
"city": ["台北", "高雄"]
}
}, {
"name": "新疆",
"cities": {
"city": ["乌鲁木齐"]
}
}]
优:
可以看到,JSON 简单的语法格式和清晰的层次结构明显要比 XML 容易阅读,并且在数据交换方面,由于 JSON 所使用的字符要比 XML 少得多,可以大大得节约传输数据所占用得带宽。
劣:
注意:
http://www.bejson.com/
6.把Python的datetime时间数据类型,转换成json字符串的方式
class DatetimeSerializer(json.JSONEncoder):
"""
实现 date 和 datetime 类型的 JSON 序列化,以符合 公司数据格式要求。
""" def default(self, obj):
if isinstance(obj, datetime.datetime):
head_fmt = "%Y-%m-%d %H:%M:%S"
return "{main_part}.{ms_part}".format(
main_part=obj.strftime(head_fmt),
ms_part=int(obj.microsecond / 1000))
elif isinstance(obj, datetime.date):
fmt = '%Y-%m-%d'
return obj.strftime(fmt)
return json.JSONEncoder.default(self, obj)
date 和 datetime 类型的 JSON 序列化
def to_json(self, d):
return json.dumps(d, cls=DatetimeSerializer)
Ajax是什么?
AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,可以指定json),相对于Form表单而言的,提交时可以偷偷向后台发数据,页面不刷新;
2大特点:
1、和server端异步交互
2、偷偷向server端发送数据,页面
和form、a标签的区别
ajax、form、a标签都可以基于HTML页面向server端发送request,
但本质区别是form、a标签一般向server索要的是页面,而ajax则是字符串数据;
Jquery和Ajax关系:
Jquery没有Ajax功能,它之所以可以调用Ajax向服务端提交数据,是因为Jquey封装了原生Ajax的代码
使用原生Ajax的优势:
使用Ajax直接使用JS的XMLHttp Request对象, 无需引入Jquery了。这样响应客户端携带信息量减少,可节省流量。
一、Ajax种类
0、在发送ajax之前初始化ajax设置, beforeSend 函数;(如何在发送ajax之前,做一些操作)
例如设置发送ajax需要携带的CSRF-TOCKEN
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
// 请求头中设置一次csrf-token
if(!csrfSafeMethod(settings.type)){
xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
}
}
});
1、jQueryAjax
不再过多赘述,就是jQuery框架封装了原生Ajax实现出来的;
<script>
$('p button').click(function () {
var $user=$('p input').val()
d={
"name": "中国",
"province": [{
"name": "黑龙江",
"cities": {
"city": ["哈尔滨", "大庆"]
}
}, {
"name": "广东",
"cities": {
"city": ["广州", "深圳", "珠海"]
}
}, {
"name": "台湾",
"cities": {
"city": ["台北", "高雄"]
}
}, {
"name": "新疆",
"cities": {
"city": ["乌鲁木齐"]
}
}]
}
d=JSON.stringify(d)
$.ajax({
url:'/ajax/',
type:'POST',
{# traditional:一般是我们的data数据有数组时会用到 #}
traditional:true,
data:d,
{# ----------------- ajax的回调函数----------------------#}
{# 1、server端response 200成功,执行的回调函数#}
success:function (data) {
data=JSON.parse(data)
console.log(typeof data)},
{# 2、erver端 response错误,执行的回调函数 #}
error:function () {
console.log(arguments)
alert(123) },
{# 3、无论server端返回的结果如何,都会执行的回调函数#}
complete:function () {
alert(321) },
{# 4、根据server端返回的状态码,执行的回调函数#}
statusCode:{
'403':function () {alert(403)},
'503':function () {alert(503)} }
})
})
</script>
Django 响应错误状态码
def Ajax(request):
d=json.loads(request.body)
print(d)
province=d['province'][0]
print(province)
d={'city': ['哈尔滨', '大庆']}
HttpResponse.status_code=503
# return HttpResponse(json.dumps(d))
return HttpResponse('OK')
$.ajax参数
请求参数
data:
ajax请求要携带的数据是肯定是一个json的object对象,ajax方法就会默认地把它编码成urlencode (urlencoded:?a=1&b=2)就像form表单、a标签格式的数据发送给server,此外,ajax默认以get方式发送请求。 注意:因为ajax要携带的数据是json的object对象,也会默认编码成urlcode格式,思考 如果你用 requests模块或者原生ajax向server发送数据、或者发送json数据,应该怎么做?
当然要指定 数据content-Type 和报头信息? #-----------------------------------------------------------------
processData:声明当前的data数据是否进行转码或预处理,默认为true,即预处理;if为false,
那么对data:{a:1,b:2}会调用json对象的toString()方法,即{a:1,b:2}.toString()
,最后得到一个[object,Object]形式的结果。 #----------------------------------------------------------------------- contentType:默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。
用来指明当前请求的数据编码格式;urlencoded:?a=1&b=2;如果想以其他方式提交数据,
比如contentType:"application/json",即向服务器发送一个json字符串:
$.ajax("/ajax_get",{ data:JSON.stringify({
a:22,
b:33
}),
contentType:"application/json",
type:"POST", }); //{a: 22, b: 33} 注意:contentType:"application/json"一旦设定,data必须是json字符串,不能是json ----------------------------------------------
traditional:一般是我们的data数据有数组时会用到 :data:{a:22,b:33,c:["x","y"]},
traditional为false会对数据进行深层次迭代;
响应参数
/* dataType: 预期服务器返回的数据类型,服务器端返回的数据会根据这个值解析后,传递给回调函数。
默认不需要显性指定这个属性,ajax会根据服务器返回的content Type来进行转换;
比如我们的服务器响应的content Type为json格式,这时ajax方法就会对响应的内容
进行一个json格式的转换,if转换成功,我们在success的回调函数里就会得到一个json格式
的对象;转换失败就会触发error这个回调函数。如果我们明确地指定目标类型,就可以使用
data Type。
dataType的可用值:html|xml|json|text|script
见下dataType实例 */
2.原生的ajax
Ajax主要就是使用 【XmlHttpRequest】对象来完成请求的操作,该对象在主流浏览器中均存在(除早起的IE),Ajax首次出现IE5.5中存在(ActiveX控件)。
XmlHttpRequest对象的主要方法:
XmlHttpRequest.open("请求方法","请求的url",是否执行回调函数?) send用户发送请求 在请求体里 setRequestHead()
在请求头里设置数据 getRespnseHeaders()
获取所有响应头数据 getRespnseHeader(响应头)
获取响应头中指定得header对应值 abort 终止请求
XmlHttpRequest对象的属性:
bj.readyState XMLHttpResposr的状态 0:未初始化,尚未调用open方法
1:启动调用了open方法
2:发送已经调用了send方法
3:接收状态(已经接收了部分数据)
4:完成(接收完毕服务端响应的数据) 只要对象的ready State改变就会执行该函数
xhr.onreadystatechange=function () { } obj.responseText 服务端返回的数据(字符串类型)
obj.responseXML 服务端返回的数据(XML对象) obj.number states 服务端返回的状态码
obj.response stateText 服务端返回的状态信息
使用XmlHttpRequest对象发送 GET请求
function add1() {
{# 得到一个XMLHttpRequest对象 xhr #}
var xhr=new XMLHttpRequest();
{# open打开一个http连接到指定url XMLHttpRequest请求#}
xhr.open('get','/add1/?i1=18&name=张根 ')
{# 设置请求体的数据#}
xhr.send()
{# XMLHttpRquest的状态改变这个函数的状态就会执行jquryAjax中的success回调函数就是基于此#}
xhr.onreadystatechange=function () {
if(xhr.readyState==1){console.log("对象未调用open方法")}
if(xhr.readyState==2){console.log("请求发送")}
if(xhr.readyState==3){console.log("接收中")}
if (xhr.readyState == 4) {console.log(xhr.responseText)}}
}
使用XmlHttpRequest对象发送 POST请求
function add1() { var xhr= new XMLHttpRequest()
xhr.open('post','/add1/')
xhr.send('name=张根&age=12')
}
问题出现了为什么后端request.post方法没有数据呢?
使用jQuery发送post请求jQuery会默认把 发送的数据(js对象)编码成urlencoded格式,使用原生ajax就不会了,
所以使用原生ajax发POST请求之前,请求头中 务必要指定数据的编码格式“Content-Type”, “application/x-www-form-urlencoded”才能发到server端;
function add1() {
var xhr= new XMLHttpRequest()
xhr.open('post','/add1/')
xhr.setRequestHeader("ConTent-Type" ,"application/x-www-form-urlencoded")
xhr.send('name=张根&age=12')
}
3、iframe标签+form表单伪造Ajax
所谓伪装Ajax操作就是不利于任何Ajax,利于其他技术向后台发送数据,这个其他的技术要从 iframa标签说起。。。。。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎来到乐X网</title>
</head>
<body> <iframe style="width:1000px; height:2000px" src="https://www.hhh286.com/htm/movieplay1/6748.htm" ></iframe> </body>
</html>
神奇的一幕发生了 自动跳转到其他网站了
还可以 这么玩
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎来到乐C网</title>
</head>
<body>
<div>
<input type="text" id="txt1">
<input type="button" value="查看" onclick="cheangurl()">
</div>
<iframe id="ifr" style="width:1000px; height:2000px" src="https://www.baidu.com" ></iframe> </body> <script>
function cheangurl() {
var inpu=document.getElementById('txt1').value
document.getElementById('ifr').src=inpu
} </script>
</html>
玩了2把就得出结论了
1、iframe标签可以不刷新发送http请求特性
2、服务端返回什么值 就 iframe标签中就会显示什么
思考:form表单和 iframe标签配合起来不就可以伪造 ajax请求了!
<form action="/fakeajax/" method="post" target="ifr">
{# target="ifr" taget目标靶子 表示From不直接把打包的input标签数据提交到后台,而是通过属性为 ifr的iframe标签 #}
<iframe name="ifr" style="display: none"></iframe>
<input name="user" type="text">
<input type="submit" value="提交">
</form>
form把数据提交给 iframe标签间接向服务端发送POST请求,既向后台发送了数据,页面也不会刷新,但是怎么模拟回调函数呢?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>伪造Ajax</title>
</head>
<body> <input type="text">
<form action="/fakeajax/" method="post" target="ifr">
<iframe name="ifr" style="display: block" onload="loadiframe()"></iframe>
{# 当iframe加载时,也就是有返回值的时候 执行loadiframe() 模拟回调函数#}
<input name="user" type="text">
<input type="submit" value="提交">
</form>
</body>
<script>
function loadiframe() {
alert('回来了')
}
</script>
</html>
会报错因为 加载<iframe name="ifr" style="display: block" onload="loadiframe()"></iframe>第一次加载触发onload时间 但是JS代码还在下面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>伪造Ajax</title>
</head>
<body> <input type="text">
<form id="f1" action="/fakeajax/" method="post" target="ifr">
<iframe name="ifr" id="ifr"></iframe>
{# 当iframe加载时,也就是有返回值的时候 执行loadiframe() 模拟回调函数#}
<input name="user" type="text">
<a onclick="submit_form()">提交 </a>
</form>
</body>
<script>
function submit_form() {
document.getElementById('f1').submit()
document.getElementById('ifr').onload=loadiframe
}
function loadiframe() {
alert('回来了')
}
</script>
</html>
最终版
iframe标签中 值不是简单的文本而是又嵌套了一个页面,如何获取iframe标签中的值 ?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>伪造Ajax</title>
</head>
<body> <input type="text">
<form id="f1" action="/fakeajax/" method="post" target="ifr">
<iframe name="ifr" id="ifr"></iframe>
{# 当iframe加载时,也就是有返回值的时候 执行loadiframe() 模拟回调函数#}
<input name="user" type="text">
<a onclick="submit_form()">提交 </a>
</form>
</body>
<script>
function submit_form() {
document.getElementById('f1').submit()
document.getElementById('ifr').onload=loadiframe
}
function loadiframe() {
var return_values=document.getElementById('ifr').contentWindow.document.body.innerHTML
console.log(return_values)
}
</script>
</html>
二、基于Ajax上传文件并预览
不管是原生ajax和jQuery都可以依赖JS中一个FormData对象上传文件
上面我们已经尝试过使用原生的ajax发送字符串数据,那怎么上传文件呢?且听 京西沙河淫王娓娓道来。。。。。。。
话说 想要使用原生的ajax要想发送文件,就必须借助JS中formdata对象,( var formdata=new FormData())
帮我们把文件 构造成特定的请求体和请求头,注意发送字符串时要自定义请求头中ConTent-Type,现在不用多此一举了;
1、原生的ajax
前端
!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>原生Aja上传文件</title>
</head>
<body>
<h1>原生ajax上传文件</h1>
<p><input type="file" id="f1"></p>
<p><input id="f2" type="button" onclick="fileup()" value="上传"></p>
</body>
<script>
function fileup(){
var formdata=new FormData()
{# 要想发文件必须借助一个特殊的 formdata对象,帮助我们封装 文件对象 #}
formdata.append('k1','v1')
var xhr= new XMLHttpRequest()
xhr.open('POST','/fileup/')
{# xhr.setRequestHeader("ConTent-Type" ,"application/x-www-form-urlencoded")#}
{# 切记 既然文件对象帮我们做了文件封装,#}
{# 也包括了请求头"ConTent-Type,就无需在像原来发字符串的时候加"ConTent-Type了#}
xhr.send(formdata)
xhr.onreadystatechange=function () {
if(xhr.readyState==4){alert(xhr.responseText)}
} }
</script>
</html>
后端
def fileup(request):
if request.method=='GET':
return render(request,'up_file.html')
else:
print(request.POST,request.FILES)
return HttpResponse('OK')
使用formdata对象做图片预览
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>原生Aja上传文件</title>
</head>
<body>
<h1>原生ajax上传文件</h1>
<div id="container"></div>
<p><input type="file" id="f1"></p>
<p><input id="f2" type="button" onclick="fileup()" value="上传"></p>
</body>
<script>
function fileup(){
var formdata=new FormData()
{# 要想发文件必须借助一个特殊的 formdata对象,帮助我们封装 文件对象 #}
formdata.append('k1','v2')
formdata.append('k1',document.getElementById('f1').files[0])
{# 获取文件对象.files得到是一个列表(全部的文件对象)获取第1个切片[0]#}
var xhr= new XMLHttpRequest()
xhr.open('POST','/fileup/')
{# xhr.setRequestHeader("ConTent-Type" ,"application/x-www-form-urlencoded")#}
{# 切记 既然文件对象帮我们做了文件封装,#}
{# 也包括了请求头"ConTent-Type,就无需在像原来发字符串的时候加"ConTent-Type了#}
xhr.send(formdata)
xhr.onreadystatechange=function () {
if(xhr.readyState==4){
var filepath=xhr.responseText
{# 获取服务端返回的文件路径#}
var tag=document.createElement('img')
tag.src="/"+filepath
{# 在本地生成一个img标签显示#}
document.getElementById('container').appendChild(tag) }
}
后端
def fileup(request):
print('ok')
if request.method=='GET':
return render(request,'up_file.html')
else:
print('OK')
fileobj=request.FILES.get('k1')
filepath=os.path.join('static',fileobj.name)
with open(filepath,'wb') as f:
for chunk in fileobj.chunks():
f.write(chunk)
return HttpResponse(filepath)
2、jQuery Ajax文件上传预览
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>原生Aja上传文件</title>
</head>
<body>
<h1>原生ajax上传文件</h1>
<div id="container"></div>
<p><input type="file" id="f1"></p>
<p><input id="f2" type="button" onclick="Queryup()" value="上传"></p>
<script src="/static/zhanggen.js"></script>
<script>
function Queryup() {
var formdata=new FormData()
{# $(document.getElementById('f1')) #}
{# doc对象转换成Jquery对象 $(doc对象) #}
{# jQueryup对象转成doc对象 jQuery对象[0] #}
{# $('#f1')[0]#}
formdata.append("k1", $('#f1')[0].files[0])
$.ajax({
url:'/fileup/',
type:'POST',
contentType:false,
{# 告诉Jquery不要对请求头做特殊处理,因为formDta已经把数据封装好了#}
processData:false,
data:formdata ,
success:function (args) {
var ele=document.createElement('img')
ele.src="/"+ args
document.getElementById('container') .appendChild(ele)
}
})
} </script>
</body>
</html>
3.iframe+form标签伪造ajax操作(兼容性更好)
由于FormData对象是HTML5之后提出的新对象,不兼容之前老版本的浏览器;
一般JS的上传插件都是通过 iframe+form伪造出来的,所以这种上传方法的兼容性会更好些;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>伪造Ajax上传</title>
</head>
<body>
<h1>伪造Ajax上传</h1>
<form method="post" id="f1" action="/fileup/" target='ifr'enctype="multipart/form-data">
<p><input type="file" name="k1"></p>
<p><iframe id="ifr"name="ifr" style="display: none"></iframe></p>
<p><input type="button" value="提交" onclick="upfile()"></p>
</form>
<div id="container"></div>
</body>
<script>
function upfile() {
{# 找到iframe标签在线绑定事件 页面加载事件()#}
document.getElementById('ifr').onload=loadIframe
{# 使用.submit()方法 提交表单#}
document.getElementById('f1').submit()
}
function loadIframe() {
{# 服务端有返回值 iframe标签就会加载,利用此特性绑定 加载事件,然后创建img标签,apendchilder到 一个div中显示 #}
var return_value=document.getElementById('ifr').contentWindow.document.body.innerHTML
var tag=document.createElement('img')
tag.src='/'+return_value
document.getElementById('container').appendChild(tag)}
</script>
</html>
4.Ajax文件上传方式总结
上传方法总结
上传文件--->iframe+input(伪造ajax)
上传数据---->Jquery、XMLHttpRespose(原生ajax)
图片预览功能实现思路:
1、上传图片到服务端
2、服务端返回一个URL到客户端
3、客户端再去通过img标签src服务端的返回的URL地址
5.ajax长连接(不断刷新)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/static/jquery-3.2.1.js"></script>
</head>
<body>
<div id="time">{{ c_time }}</div>
</body>
<script>
$(function () {
GetTime()
}); function GetTime() {
$.ajax({
url:{% url 'gettime' %},
type: 'POST',
data: {'csrfmiddlewaretoken': "{{ csrf_token }}"},
dataType: 'JSON',
success: function (res) {
$('#time').text(res);
GetTime() }
})
}
</script>
</html>
不断更新当前时间
三、jsonp跨域
一般来说位于www.Laden.com下的网页,是无法和 www.Aobam.com以及任何其他服务器跨域沟通的,由于浏览器同源策略!
什么是同源策略呢?
1.当客户端发送一个GET请求 服务端返回字符串(字符串若包含JS代码,再让浏览器去其他网站获取数据)
2.这时客户端(浏览器)就不能再去发送请求到其他服务端的(除非带有src属性的标签例外)
3.如果客户端发送了请求到其他服务端下,其他服务器也会收到,但在其他服务端再返回到浏览器时会被浏览器阻止掉
实验证明
API(http://127.0.0.1:8000/)
def data(request):
print('跨域请求来了!!')
userlist=["alex","egon",'eric']
return HttpResponse(json.dumps(userlist))
跨域者(http://127.0.0.1:8086)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h1>jsop</h1>
<ul id="user"> </ul>
<input type="button" value="获取API的用户列表" onclick="getusers()">
</body>
<script src="/static/zhanggen.js"></script>
<script>
function getusers(){
var xhs=new XMLHttpRequest()
xhs.open('GET','http://www.api.com:8000/data/')
xhs.send()
xhs.onreadystatechange=function () {
if(xhs.readyState==4){
var content=xhs.responseText
console.log(content)
}
}
} </script>
</html>
思考:
浏览器的同源策略不会限制带有src属性的标签跨域向其他服务器发送请求
有些程序员机制的利用了这一点,绕开了浏览器的同源策略,发明了jsonp既保证了浏览的安全策略,也解决了浏览器跨站访问数据的问题;
Jsonp原理
啰嗦版
1.定义个名为的函数 列入名为b;
2.使用JS动态创建script标签(例如:tag.src='http://www.api.com:8000/data/?functionname=b)通过带有src属性的script标签,跨域向其他服务器发送GET请求;
所以JSONP只能发送GET请求
3.其他服务器收到后 获取函数名 v=request.GET.get('functionname')
两人交互约定很重要啊
4.由于客户端浏览器收到了函数名+括号会立即执行 最初定义的函数B
简洁版
1、客户端定义函数
2、客户端把函数名发给其他服务端
3.其他服务端 拼接一个 函数(参数)返回给客户端
4.客户端执行
一言以敝之版
客户端定义函数,服务端字符串拼接 函数、()、参数,返回客户端,客户端执行最初定义的函数(参数)
代码版
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h1>jsop</h1>
<ul id="user"> </ul>
<input type="button" value="获取API的用户列表" onclick="getusers()">
</body>
<script src="/static/zhanggen.js"></script>
<script >
function getusers() {
var tag=document.createElement('script')
tag.src='http://www.api.com:8000/data/?functionname=b'
document.head.appendChild(tag) }
function b(args) {
document.getElementById('user').innerHTML=args
} </html>
其他服务器
def data(request):
v=request.GET.get('functionname')
print('跨域请求来了!!')
userlist=["alex","egon",'eric']
temp='%s(%s)'% (v,userlist)
return HttpResponse(temp)
既然傻傻的你,早已看透了JSONP跨域访问的一切,JjQuery也会,于是它可以发送JSONP请求封装在了自己的ajax里面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h1>jsop</h1>
<ul id="user"> </ul>
<input type="button" value="获取API的用户列表" onclick="getusers()">
</body>
<script src="/static/zhanggen.js"></script>
<script >
$.ajax({
url:'http://www.api.com:8000/data/',
type:'get',
dataType:'jsonp',
jsonp:'functionname',
jsonpCallback:'b'
})
}
function b(args) {
document.getElementById('user').innerHTML=args
}
</script> </html>
三、CORS跨站资源共享
看完了jsonp的跨域方式,是不是赶紧有些复杂呢?而且还只能发跨域的GET请求! 我就TM想跨域访问,还是我情他愿的事情,咋就浏览器就非得给我阻挡一下子。
其实不是的只要第三方网站,返回客户端时响应头里有特殊标记(令牌), 浏览器看到就不会阻止了这就是CORS跨站共享;
简单请求(1次请求1次响应)
请求方式:HEAD、GET、POST
def newdata(request):
userlist = ["alex", "egon", 'eric']
userlist=json.dumps(userlist)
obj=HttpResponse(userlist)
obj['Access-Control-Allow-Origin']='http://www.zhanggen.com:8086'
# 允许http://www.zhanggen.com:8086访问本域下的数据
return obj
允许所有客户端跨站访问本域名下的数据
def newdata(request):
userlist = ["alex", "egon", 'eric']
userlist=json.dumps(userlist)
obj=HttpResponse(userlist)
# obj['Access-Control-Allow-Origin']='http://www.zhanggen.com:8086'
# 允许http://www.zhanggen.com:8086访问本域下的数据
obj['Access-Control-Allow-Origin']='*'
# 允许所有人访问本域下的数据
return obj
复杂的请求(2次请求2次响应)
请求方式 options
其实有些请求方式会发2次请求带服务端(多一个预检环节)
例如delete请求会以option的方式发送1个预检的请求(不同于get/post请求,不发请求头,请求体)
如果服务端响应客户端允许操作之后
客户端校验 再发delete请求
def newdata(request):
if request.method=='OPTIONS':
print('预检')
obj=HttpResponse()
#允许所有客户端跨站访问本域数据
obj['Access-Control-Allow-Origin'] ="*"
#允许客户端使用delete方法
obj["Access-Control-Allow-Methods"]="DELETE"
return obj
else:
obj=HttpResponse('OK')
#客户端使用delete方法发送第2次请求时,也要设置响应头允许
obj['Access-Control-Allow-Origin'] = "*"
return obj
博客链接:
银角大王:http://www.cnblogs.com/wupeiqi/articles/5703697.html
二龙湖浩哥:http://www.cnblogs.com/yuanchenqi/articles/7429279.html#3769378
Json+Ajax相关的更多相关文章
- AJAX 相关笔记
AJAX (Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)). 平时工作中使用ajax的频率挺高的,这里整理了一些ajax相关的小知识,后续 ...
- JSON & Ajax
Ajax是异步JavaScript和XML是用来在客户端作为一组相互关联的Web开发技术,以创建异步Web应用程序. Ajax模型,Web应用程序可以发送数据和检索数据从一个服务器,而不干扰现有的页面 ...
- jquery json ajax
当html中用script包含了不在同一个目录下的js外部文件(主要是为了通用代码的重用)时,这个js文件的 内容就如同在当前html文件中了,写jquery的时候不用考虑路径问题,可以直接引用htm ...
- js常见知识点1.ajax相关
一. javascript中的typeof返回哪些数据类型? 建议回复: typeof 运算符把类型信息当作字符串返回.typeof 返回值有六种可能: number, string, boolean ...
- JavaScript之JSON&AJAX
今天为大家讲解JavaScript中非常流行的数据传输形式JSON和异步技术AJAX技术. 一 JSON JSON的全称是JavaScript Object Notation(js对象表示法),它是一 ...
- Django——Ajax相关
Ajax简介 AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即使用Javascript语言与服务器进行异步交互,传输的数 ...
- 前后端分离构架 与 json ajax简介
前后端分离 传统开发方式 曾几何时,JSP和Servlet为Java带来了无限风光,一时间大红大紫,但随着互联网的不断发展,这样的开发方式逐渐显露其弊端,在移动互联网炙手可热的今天,应用程序对于后台服 ...
- JSON&AJAX
JSON 定义:JSON(JavaScript Object Notation, JS 对象简谱)是一种轻量级的数据交换格式.它基于 ECMAScript(欧洲计算机协会制定的 JS 规范)的一个子集 ...
- ecshop JSON,ajax.call 异步传输
1.res = Ajax.call('user.php?act=depot_id', 'id='+v,null,"GET", "JSON",false); 2. ...
随机推荐
- linux获取某一个网卡的ipv4地址
ip a show ens33 | grep inet | grep -v inet6 | awk '{print $2}' | awk -F '/' '{print $1}'
- cubase 的FX轨道使用方法
FX为辅助通道!
- Elasticsearch索引操作
一.索引初始化操作 插件推荐使用head.marvel (收费) 1.1 创建新索引 curl -XPUT 'http://localhost:9200/test' -d ' { "sett ...
- 中国剩余定理(crt)和扩展中国剩余定理(excrt)
数论守门员二号 =.= 中国剩余定理: 1.一次同余方程组: 一次同余方程组是指形如x≡ai(mod mi) (i=1,2,…,k)的同余方程构成的组 中国剩余定理的主要用途是解一次同余方程组,其中m ...
- 浏览器内核与BOM对象介绍
BOM(Browser Object Model)对象介绍 我们都知道js有三部分组成,ECMAScript.DOM和BOM,根据宿主(浏览器)的不同,具体的表现形式也不尽相同,ie和其它浏览器也是风 ...
- linux内核 同步
锁 linux本身实现了集中锁机制,各种锁机制之间的差别是,当锁已经被其他线程持有的时候,一些锁使用自旋的方式来等待,另外一些锁会当当前线程改变为睡眠状态然后等待被唤醒. 锁的争用 如果一个锁处于高度 ...
- Date 对象
JavaScript Date 对象 Date 对象 Date 对象用于处理日期与时间. 创建 Date 对象: new Date() 以下四种方法同样可以创建 Date 对象: var d = ne ...
- 关于redis的主从、哨兵、集群(转)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/c295477887/article/de ...
- C#双缓冲解释
C#双缓冲解释 简单说就是当我们在进行画图操作时,系统并不是直接把内容呈现到屏幕 C#双缓冲 上,而是先在内存中保存,然后一次性把结果输出来,如果没用双缓冲的话,你会发现在画图过程中屏幕会闪的很厉害, ...
- BZOJ 2976: [Poi2002]出圈游戏 Excrt+set
人数很少,可以直接用 $set$ 来模拟人的情况. 然后就能得到若干个方程,用 $excrt$ 进行合并即可. #include <set> #include <cmath> ...