前言:有时候一忙起来就没了时间观念,原来我已经有十多天没写博客了。一直想做跨域方面的尝试,无奈最近准备校招没时间动动手。今天就先讲讲JSONP吧,昨晚还在研究QQ空间日志里面网络图片的问题呢,我发现日志还提供了HTML模式,我们可以利用img标签的src属性实现跨域请求,从自己的服务器里提取动态内容。

JSONP

  在讲实现之前,我们先来看看何为JSONP。以下是维基百科的解释:

  JSONP or "JSON with padding" is a communication technique used in JavaScript programs running in web browsers to request data from a server in a different domain, something prohibited by typical web browsers because of the same-origin policy. JSONP takes advantage of the fact that browsers do not enforce the same-origin policy on <script> tags. Since it works through <script> tags, JSONP supports only the GET request method. There are significant security implications and risks associated to using JSONP; unless you have no choice, CORS is usually the better choice.

  我粗陋翻译一下:JSONP又称JSON with padding,它是用在浏览器上运行的JS程序里的一项交互技术,目的是为了从不同的服务器域名上请求数据。由于同源政策的限制,部分功能会受到浏览器的禁止。JSONP利用的是浏览器不会对<script>标签实施同源政策的情况。又因为它是通过<script>作用的,所以JSONP只支持GET请求方式。但值得注意的是,使用JSONP会存在安全隐患和危险。CORS(跨域资源共享,Cross-Origin Resource Sharing)是一个更为常用的佳选,除非你没得选。

解释:  

  简单来说就是,一般情况下,在本域名的页面想要获取其他域名下的数据是会受到限制的。但是在HTML页面中的<script>(img,iframe亦可)就突破了这种限制,可以通过src属性来访问其他域名并获得返回的数据,但这种方法并不安全,只能通过GET方法获取。

  其实我们平常稍加留意,就不难发现其实我们平常在页面中使用CDN也是这个原理,我们的页面同样可以访问其他服务器上的JS文件。

  如我们常用的百度CDN,我们通常在<head>里面加上是<script>标签就可以使用其他服务器的CDN。

  <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.js"></script>

  只不过稍有不同的是现在变为向服务器运行文件请求数据,然后再以JavaScript的形式返回。

客户端实现:

  JSONP是一种非正式传输协议,具体传输内容以及格式可以由用户自己定义。不过我觉得JSONP可能会在ES6中新增也说不定哦,到时候可能会规范传输格式。JSONP其中有一个要点就是允许用户传递一个callback参数给服务端,然后服务端输出的数据作为callback的参数再一并返回到客户端页面,最后根据参数在客户端页面执行这个回调函数,最终达到返回数据并处理的目的。

  代码形式如下:

 <head>
<meta charset="UTF-8">
<title>JSONP</title>
<script type="text/javscript">
var cbFn = function(str){
alert(str);
}
</script>
<script src="http://www.sp0.baidu.com?data=value&cb=cbFn"></script>
</head>

  首先要预定义一个回调函数,用于处理返回数据;其次请求数据的<script>标签的src要传递请求参数以及回调的函数名字到后台,这一点要沟通协调好。

  由于在实际应用中请求地址、请求参数以及次数都是不固定的,所以我们要把JSONP封装成一个函数,增强灵活性和复用性。

   var s1;
function jsonp(url,data,cb){
data.cb = cb?cb:"callback";
data.t = new Date().getTime();
for (var i in data){
var str = i+"="+data[i];
arr.push(str);
}
var str = url+"?"+arr.join("&");
var headEl = document.getElementsByTagName("head")[0];
if (s1){
headEl.removeChild(s1);
}
s1 = document.createElement("script");
s1.src = str;
headEl.appendChild(s1);
17 }

  代码解释:首先给传递的数据中插入一个回调函数名和一个新的时间参数值,让后台获取你要回调的函数名以及防止调用缓存。接下来就是判断之前已经是否发送过JSONP请求,如果存在,则删除重建。

服务端实现:

  假设我在客户端执行了以下请求

 jsonp("http://www.chengguanhui.com/test.php",{
name:"ray",
age:23
},"cbFn"); cbFn(str){
alert(str);
}

  那么HTTP传递的URL为http://www.chengguanhui.com/test.php?name=ray&age=23cb=cbFn&t=242566(某个不定时间值)

  PHP代码:

 <?php
require_once("common.php");
$name = $_GET['name'];
$age = $_GET['age'];
$cb = $_GET['cb'];
$str = $name.$age;
echo $cb."(".$str.")";
?>

  客户端接收到cbFn("ray23")并弹出对应内容。

JQ实现:

  $.ajax(url,[settings])

  $.ajax({
type: "get",
url: "http://www.chengguanhui.com/test.php",
dataType: "jsonp",
data: "name=ray&age=23",
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
jsonpCallback:"handleFn",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
success: function(json){
alert(json.name+json.age);
},
error: function(){
alert('fail');
}
});
});

  $.getJSON(url,data,callback)

 $.getJSON("http://www.chengguanhui.com/test.php",//如果请求值固定时,可以省略data参数而直接写在url参数里。
{
name:ray,
age:23
},
function(data){
$.each(data.items, function(i,item){
alert(i+item);
});
});

  说明:原创文章,转载全文内容或非翻译内容时,请注明出处与作者。谢谢。

最新文章

  1. Tomcat+Nginx+Lvs部署方案与性能调优
  2. ACM之Java速成(3)
  3. ajax连接数据库并操作数据库
  4. 在VMware中为Linux系统安装VM-Tools的详解教程
  5. Mysql源码安装
  6. 走进C标准库(2)——&quot;stdio.h&quot;中的fopen函数
  7. 安卓高仿QQ头像截取升级版
  8. iOS中分段控制器与UIScrollView结合使用
  9. HNOI2019 苟命记
  10. 给hive的metastore做JVM优化
  11. 关于eric4和pyqt的入门学习(转)
  12. SQL注入之Sqli-labs系列第四十六关(ORDER BY注入)
  13. Hass.io: add-on Configurator
  14. 远程连接MySQL MySQL的远程连接
  15. ACM/ICPC 2018亚洲区预选赛北京赛站网络赛-B:Tomb Raider(二进制枚举)
  16. 腾讯云JavaWeb环境配置
  17. APP-6-百度地图导航
  18. Flink standalone模式作业执行流程
  19. PostgreSQL代码分析,查询优化部分,canonicalize_qual
  20. VC++中如何复制对话框资源

热门文章

  1. Bounce.js – 快速创建漂亮的 CSS3 动画效果
  2. Windows GUI代码与Windows消息问题调试利器
  3. 200、301、302、304、404等HTTP状态码
  4. Android Studio快捷键每日一练(3)
  5. codeMirror插件使用讲解
  6. angularjs input上传图片前获取图片的Size
  7. 用Visual Studio Code 开发应用之 安装 Visual Studio Code
  8. MVC 4.0 学习中遇到的bug
  9. The service cannot be activated because it does not support ASP.NET compatibility
  10. 基于MVC4+EasyUI的Web开发框架经验总结(1)-利用jQuery Tags Input 插件显示选择记录