jsonp vs ajax

1、ajax 和 jsonp 这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jQuery和ExtJS等框架都把jsonp作为ajax的一种形式进行了封装。
2、但 ajax和jsonp本质上是不同的东西,jsonp不是ajax的一个特例ajax的核心是通过XmlHttpRequest对象获取非本页内容,而jsonp的核心是通过动态添加<script>标签来调用服务器提供的 js 文件
3、其实ajax和jsonp的区别不在于是否跨域,ajax通过服务端代理一样可以实现跨域,jsonp本身也不排斥同域的数据获取。
4、jsonp是一种方式或者说非强制性协议,跟ajax一样,jsonp也不一定非要用json格式来传递数据,如果你愿意,字符串都行,只不过这样不利于用jsonp提供公开服务。

JSONP(非官方的跨域数据交互协议)
使用JSON来传递数据, 通过JSONP来实现跨域
ajax 直接请求远程服务器的文件时,存在跨域(协议+域名+端口)无权限访问的问题。
三种跨域的解决办法:
1、ajax可以通过服务端代理实现跨域
2、在远程服务端处理请求时添加这句话:response.setHeader("Access-Control-Allow-Origin", "*"); 不过这样做的话,服务端的安全性很低,因为 Access-Control-Allow-Origin : * 表示允许任何域名跨域访问。不过可以把 * 换成指定的域名,如http://www.client.com,这样就只允许这个域名跨域访问到服务器。
3、通过JSONP来实现跨域,比较常用。不过JSONP只支持GET请求,POST请求会被自动转换为GET请求进行处理,保险起见,还是不要写成POST。JSONP本质上是一种脚本注入行为,有一定的安全隐患。

JSONP原理:动态添加一个<script>标签,而script标签的src属性是没有跨域限制的。所以这种跨域方式其实与ajax的XmlHttpRequest协议无关。
客户端将 服务端请求地址需要传入的参数回调函数名(需要服务端返回的JS文件中的函数名)通过script标签的src属性以GET请求的方式发送给服务端。例如:<script src="http://server?A=a&B=b&callback=callBackFunctionName"></script>。script标签中的JS文件都是以GET方式请求得来的,所以 JSONP只支持GET请求
服务端返回一个JS文件给客户端,这个JS文件中有一个函数,函数名为上面的回调函数名(由客户端自定义),这个函数的参数是一个JSON对象,JSON对象中的数据就是客户端所请求的。

JSONP的实现逻辑:JSONP是发现,而不是发明,因为这其中并没有新的知识点。
1、在 客户端的JS中声明函数并定义好方法体,例如:function callBackFunctionName(data) { 方法体,对传入的data进行数据处理 } 其中,callBackFunctionName是由客户端自定义的回调函数名,data是函数的形参!这个函数要在全局作用域中定义。
2、 两种方式在客户端的JS中动态添加一个<script>标签,或者 在callBackFunction声明定义的script标签块下面(例如body标签的最下面, 该条语句一定要放在回调函数定义的后面写:<script src="http://server?A=a&B=b&callback=callBackFunctionName"></script> 。参考下面的原生JS示例,src的内容解析:http://server 是服务端请求地址(或请求的方法名);A=a&B=b 是传到服务端的请求参数;callback=callBackFunctionName 是告诉服务端返回的JS文件中的函数名应该为callBackFunctionName。
3、 服务端返回的JS文件中的函数 其实是对第1步中声明定义的函数进行调用函数调用时传入的参数就是客户端所请求的数据。例如:callBackFunctionName( JSONObject ) ; 这里函数调用时传入的实参是一个JSON对象或JSON字符串,函数被调用后就会执行第1步中的方法体,完成对数据的接收和处理。

原生JS实现JSONP示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp_demo</title>
</head>
<body>
<div id="data"></div>
<script type="text/javascript">
var dataEl = document.getElementById("data");
var script = document.createElement("script");
var url = "http://localhost:8080/demo1/WordCloudServlet?callback= dataHandler ";
script.setAttribute("src",url);
document.getElementsByTagName("head")[0].appendChild(script);// 两种方式之一动态添加script标签
function dataHandler(data) {
dataEl.innerText = JSON.stringify(data); //这里还可以用innerHTML
}
</script>
<!-- <script type="text/javascript" src="http://localhost:8080/demo1/WordCloudServlet?callback= dataHandler"></script> -->
<!-- 另一种方式把 script标签写死,放在 body标签的最下面。 必须放在回调函数定义的 script标签块的下面 -->
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值