【JavaScript】--重点解析之跨域请求

时间:2022-06-06 15:22:15

JSON

  JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。

  JSON是用字符串来表示Javascript对象,例如可以在django中发送一个JSON格式的字符串给客户端Javascript,Javascript可以执行这个字符串,得到一个Javascript对象。

  json就是js对象的一种表现形式(字符串的形式)

JSON对象语法

  json语法:

  • 数据在名称/值对中
  • 数据由逗号分隔
  • 花括号保存对象(对象需要使用大括号起来)
  • 方括号保存数组(数组使用中括号括起来)
var person = {"name":"zhangSan", "age":"", "sex":"male"};
alert(person.name + ", " + person.age + ", " + person.sex);

注意,key也要在双引号中!

JSON值:

  • 数字  (整数或浮点数)
  • 字符串(在双引号中)
  • 逻辑值(true 或 false)
  • 数组   (在方括号中)
  • 对象   (在花括号中)
  • null
var person = {"name":"alex", "age":"", "sex":"male", "hobby":["girl", "movie", "travle"]};
alert(person.name + ", " + person.age + ", " + person.sex + ", " + person.hobby);

带有方法的JSON对象:

var person = {"name":"alex",
"sex":"men",
"teacher":{
"name":"tiechui",
"sex":"half_men",
},
"bobby":['basketball','running'], "getName":function() {return 80;}
};
alert(person.name);
alert(person.getName());
alert(person.teacher.name);
alert(person.bobby[0]);

js接受python的json对象:

在json的编码过程中,会存在从python原始类型向json类型的转换过程,具体的转换
如下: python --> json
dict object
list,tuple array
str,unicode string
int,long,float number
True true
False false
None null

js与django的交互

def login(request):
obj={'name':"alex111"}
return render(request,'index.html',{"objs":json.dumps(obj)})
#----------------------------------
<script>
var temp={{ objs|safe }}
alert(temp.name);
alert(temp['name'])
</script>

JSON与XML比较

  • 可读性:   XML胜出;
  • 解码难度:JSON本身就是JS对象(主场作战),所以简单很多;
  • 流行度:   XML已经流行好多年,但在AJAX领域,JSON更受欢迎。

parse()和.stringify()

parse用于从一个字符串中解析出json对象,如

var str = '{"name":"yuan","age":"23"}'

结果:

JSON.parse(str)

Object

age: ""
name: "yuan" 注意:单引号写在{}外,每个属性名都必须用双引号,否则会抛出异常。 stringify()用于从一个对象解析出字符串,如 var
a = {a:1,b:2} 结果: JSON.stringify(a) "{"a":1,"b":2}"

 跨域请求

  同源策略机制

  浏览器有一个很重要的概念——同源策略(Same-Origin Policy)。所谓同源是指,域名,协议,端口相同。不同源的客户端脚本(javascript、ActionScript)在没明确授权的情况下,不能读写对方的资源。

  简单的来说,浏览器允许包含在页面A的脚本访问第二个页面B的数据资源,这一切是建立在A和B页面是同源的基础上。

  如果Web世界没有同源策略,当你登录淘宝账号并打开另一个站点时,这个站点上的JavaScript可以跨域读取你的淘宝账号数据,这样整个Web世界就无隐私可言了。

  jsonp的js实现

  JSONP是JSON with Padding的略称。可以让网页从别的域名(网站)那获取资料,即跨域读取数据。

  它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。

  JSONP就像是JSON+Padding一样(Padding这里我们理解为填充)

#---------------------------http://127.0.0.1:8001/login

 def login(request):
print('hello ajax')
return render(request,'index.html')
#---------------------------返回用户的index.html
<h1>发送JSONP数据</h1> <script>
function fun1(arg){
alert("hello"+arg)
}
</script>
<script src="http://127.0.0.1:8002/get_byjsonp/"></script> #-----------------------------http://127.0.0.1:8002/get_byjsonp def get_byjsonp(req):
print('8002...')
return HttpResponse('fun1("苑昊")')

  这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。

  将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义吧。

  一般情况下,我们希望这个script标签能够动态的调用,而不是像上面因为固定在html里面所以没等页面显示就执行了,很不灵活。我们可以通过javascript动态的创建script标签,这样我们就可以灵活调用远程服务了。

<script>
function addScriptTag(src){
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
function fun1(arg){
alert("hello"+arg)
} window.onload=function(){
addScriptTag("http://127.0.0.1:8002/get_byjsonp/")
}
</script>

   现在将你自己在客户端定义的回调函数的函数名传送给服务端,服务端则会返回以你定义的回调函数名的方法,将获取的json数据传入这个方法完成回调:

<script>
function addScriptTag(src){
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
function fetch(arg){
alert("hello"+arg)
} window.onload=function(){
addScriptTag("http://127.0.0.1:8002/get_byjsonp?callback=fetch")
} </script> #--------------------------------http://127.0.0.1:8002/get_byjsonp
def get_byjsonp(req): callback=req.GET.get('callback')
print(callback)
return HttpResponse('%s("yuan")'%callback)

jQuery对JSONP的实现

  jQuery框架也当然支持JSONP,可以使用$.getJSON(url,[data],[callback])方法

<script type="text/javascript">
$.getJSON("http://127.0.0.1:8002/get_byjsonp?callback=?",function(arg){
alert("hello"+arg)
});
</script>

  结果是一样的,要注意的是在url的后面必须添加一个callback参数,这样getJSON方法才会知道是用JSONP方式去访问服务,callback后面的那个问号是内部自动生成的一个回调函数名。

  当然,如果说我们想指定自己的回调函数名,或者说服务上规定了固定回调函数名该怎么办呢?我们可以使用$.ajax方法来实现

<script type="text/javascript" src="/static/jquery-2.2.3.js"></script>

<script type="text/javascript">
$.ajax({
url:"http://127.0.0.1:8002/get_byjsonp",
dataType:"jsonp",
jsonp: 'callbacks',
jsonpCallback:"fetch"
});
function fetch(arg){
alert(arg);
}
</script> #--------------------------------- http://127.0.0.1:8002/get_byjsonp
def get_byjsonp(req): callback=req.GET.get('callbacks')
print(callback)
return HttpResponse('%s("yuan")'%callback)

another way:

<script type="text/javascript" src="/static/jquery-2.2.3.js"></script>

<script type="text/javascript">
$.ajax({
url:"http://127.0.0.1:8002/get_byjsonp",
dataType:"jsonp",
jsonp: 'callbacks',
success:function(data){
alert(data)
}
}); </script>
#-------------------------------------http://127.0.0.1:8002/get_byjsonp
def get_byjsonp(req): callback=req.GET.get('callbacks')
print(callback) #jQuery223015502220591490135_1477560648881
return HttpResponse("%s('yuan')"%callback)

  没错,jsonpCallback就是可以指定我们自己的回调方法名fetch,远程服务接受callback参数的值就不再是自动生成的回调名,而是fetch。dataType是指定按照JSOPN方式访问远程服务。callback必须有,因为服务端根据它来去回调函数的名字,如果是自已定义的,那么就得有自定义的名字:jsonpCallback:"fetch";如果不加这个参数,则自动生成一个随机名字。

   利用jQuery可以很方便的实现JSONP来进行跨域访问。