跨域请求之JSONP 一
2011-05-03 06:40
323 查看
跨域请求的方式有很多种,
iframe
document.domain
window.name
script
XDomainRequest (IE8+)
XMLHTTPRequest (Firefox3.5+)
postMessage (HTML5)
后台代理
...
它们有各自的优缺点,返回的数据格式也各不同,应根据需求慎重选择。比如iframe返回html片段就比较适合,费老劲用它返回JSON就得不偿失了。这篇开始我将打造一个实用的跨域请求工具Sjax。使用script请求的最大缺点,挑战是错误处理。比如404错误,它不象XMLHTTPRequest能准确的返回状态码404。我把这个放在最后一篇。
本系列主要描述以上列举的方式4,即通过script返回JSON格式数据数据。这种方式现在称为JSONP。JSON是目前前后台沟通使用最流行,也最广泛的格式之一。相对于早期的AJAX返回XML(AJAX中的X就是XML),JSON显得更轻量级,没有多余的Tag标记,解析也是原生的。XML返回到前端后先转成文档,通过DOM API一层层的解析。解析DOM是开销比较大的,尤其在早期的IE版本中(IE6/7/8),core js与dom沟通的代价是很大的。
JSONP的实现思路很简单
前端创建script标记,设置src,添加到head中(你可以往body中添加)
后台返回一个js变量jsonp,这个jsonp就是请求后的JSON数据
回调完成后删除script标记(还有一些清理工作如避免部分浏览器内存泄露等)
接口
示例:
这个html实现一个最简单的前后台交互功能,点击按钮“Get Name”,获取到name后显示在段落P上。
clk函数中调用Sjax.load方法,Sjax中的S指script。之前我的Ajax系列中使用的Ajax命名,这里就使用了Sjax。
请求的后台url是jsonp.js,它返回如下
因为是测试,这里使用最简单的方式实现。请求的后台其实不必是js文件,可以是php,java等任何后台语言,它们可能会连接数据库进行一系列的业务查询。总之它最后返回的结构必须变量jsonp,这个变量就是一个js对象,至于有多复杂则无需关注。
好了,试试吧
相关:
跨域请求之JSONP二
https://github.com/snandy/io
// Sjax =
function(win){
var isIE = /*@cc_on!@*/!1,
doc = win.document,
head = doc.getElementsByTagName('head')[0];
function request(url, success, timestamp){
var script = doc.createElement('script');
function callback(){
if(typeof jsonp != 'undefined'){
success(jsonp);
}else{
alert('warning: jsonp did not return.');
}
// Handle memory leak in IE
script.onload = script.onreadystatechange = null;
if( head && script.parentNode ){
head.removeChild(script);
}
}
if(isIE){
script.onreadystatechange = function(){
var readyState = this.readyState;
if(readyState == 'loaded' || readyState == 'complete'){
callback();
}
}
}else{
script.onload = function(){
callback();
}
}
if(timestamp){
url += '?ts=' + (new Date).getTime();
}
script.src = url;
head.insertBefore(script, head.firstChild);
}
return {load:request};
}(this);
function clk(){
Sjax.load(
'http://files.cnblogs.com/snandy/jsonp.js',
function(){
document.getElementById('p1').innerHTML = 'Hi, ' + jsonp.name;
}
);
}
// ]]>
iframe
document.domain
window.name
script
XDomainRequest (IE8+)
XMLHTTPRequest (Firefox3.5+)
postMessage (HTML5)
后台代理
...
它们有各自的优缺点,返回的数据格式也各不同,应根据需求慎重选择。比如iframe返回html片段就比较适合,费老劲用它返回JSON就得不偿失了。这篇开始我将打造一个实用的跨域请求工具Sjax。使用script请求的最大缺点,挑战是错误处理。比如404错误,它不象XMLHTTPRequest能准确的返回状态码404。我把这个放在最后一篇。
本系列主要描述以上列举的方式4,即通过script返回JSON格式数据数据。这种方式现在称为JSONP。JSON是目前前后台沟通使用最流行,也最广泛的格式之一。相对于早期的AJAX返回XML(AJAX中的X就是XML),JSON显得更轻量级,没有多余的Tag标记,解析也是原生的。XML返回到前端后先转成文档,通过DOM API一层层的解析。解析DOM是开销比较大的,尤其在早期的IE版本中(IE6/7/8),core js与dom沟通的代价是很大的。
JSONP的实现思路很简单
前端创建script标记,设置src,添加到head中(你可以往body中添加)
后台返回一个js变量jsonp,这个jsonp就是请求后的JSON数据
回调完成后删除script标记(还有一些清理工作如避免部分浏览器内存泄露等)
接口
Sjax.load( url, // 跨越请求的URL success, // 回调函数,必须定义一个形参,用于接收后台返回的全局变量jsonp (约定后台返回如jsonp = {...}结构) timestamp, // 传true会加一个时间戳,防止缓存,默认不加 );
示例:
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>sjax_0.1.js by snandy</title> <script src="http://files.cnblogs.com/snandy/sjax_0.1.js"></script> </head> <body> <p id="p1" style="background:gold;"></p> <input type="button" value="Get Name" onclick="clk()"/> <script type="text/javascript"> function clk(){ Sjax.load( 'http://files.cnblogs.com/snandy/jsonp.js', function(){ document.getElementById('p1').innerHTML = 'Hi, ' + jsonp.name; } ); } </script> </body> </html>
这个html实现一个最简单的前后台交互功能,点击按钮“Get Name”,获取到name后显示在段落P上。
clk函数中调用Sjax.load方法,Sjax中的S指script。之前我的Ajax系列中使用的Ajax命名,这里就使用了Sjax。
请求的后台url是jsonp.js,它返回如下
jsonp = {name:'jack'};
因为是测试,这里使用最简单的方式实现。请求的后台其实不必是js文件,可以是php,java等任何后台语言,它们可能会连接数据库进行一系列的业务查询。总之它最后返回的结构必须变量jsonp,这个变量就是一个js对象,至于有多复杂则无需关注。
好了,试试吧
相关:
跨域请求之JSONP二
https://github.com/snandy/io
// Sjax =
function(win){
var isIE = /*@cc_on!@*/!1,
doc = win.document,
head = doc.getElementsByTagName('head')[0];
function request(url, success, timestamp){
var script = doc.createElement('script');
function callback(){
if(typeof jsonp != 'undefined'){
success(jsonp);
}else{
alert('warning: jsonp did not return.');
}
// Handle memory leak in IE
script.onload = script.onreadystatechange = null;
if( head && script.parentNode ){
head.removeChild(script);
}
}
if(isIE){
script.onreadystatechange = function(){
var readyState = this.readyState;
if(readyState == 'loaded' || readyState == 'complete'){
callback();
}
}
}else{
script.onload = function(){
callback();
}
}
if(timestamp){
url += '?ts=' + (new Date).getTime();
}
script.src = url;
head.insertBefore(script, head.firstChild);
}
return {load:request};
}(this);
function clk(){
Sjax.load(
'http://files.cnblogs.com/snandy/jsonp.js',
function(){
document.getElementById('p1').innerHTML = 'Hi, ' + jsonp.name;
}
);
}
// ]]>
相关文章推荐
- jquery+ajax+jsonp实现跨域请求
- JSONP跨域请求
- Ajax的jsonp跨域请求样例
- JS & jQuery 中的 jsonp (跨域请求)
- Ajax+Spring MVC实现跨域请求(JSONP)JSONP 跨域
- Java程序员从笨鸟到菜鸟(十一)JSONP解决跨域请求
- web跨域请求<一>之JSONP
- 跨域请求之JSONP 二
- jsonp 跨域请求
- 利用JQuery jsonp实现Ajax跨域请求 .Net 的*.handler 和 WebService,返回json数据
- 实现跨域请求jsonp方式
- 跨域请求之JSONP
- AJAX 跨域请求 - JSONP获取JSON数据
- 关于跨域请求和JSONP
- Jsonp和HttpClient跨域请求
- AJAX 跨域请求 - - JSONP获取JSON数据
- jsonp跨域请求详解
- AngularJS中$http.jsonp跨域请求问题
- 跨域请求之jQuery的ajax jsonp的使用解惑