AJAX的跨域与JSONP(为文章自动添加短址的功能)


Posted in Javascript onJanuary 17, 2010

什么是AJAX的跨域请求
出于安全的考虑,如果你要从www.a.com通过Ajax来请求另外一个网站www.b.com的内容,浏览器是不允许你这样做的(不理解这里的安全是指什么?想想如果没有这个限制的话,黑客可以做些什么)。那什么样的情况下算是跨域?域名不同那当然算是跨域了,例如a.com向b.com发送请求,这当然就是跨域了,不允许的。不过子域名不同(例如sub.a.com向www.a.com发送请求)甚至是同域名不同端口(例如a.com:80向a.com:8080)也算是跨域的。
下面演示一个跨域的例子:

<script type="text/javascript" > 
//jQuery代码 
$("#btnCrossDomainRequest").click(function(){ 
$.get('https://3water.com', function(data){ 
alert('success'); 
}); 
}); 
</script>

(在IE8下提示没有权限,在FF3.5.5和Google浏览器下都没有提示,汗~我记得FF以前的版本是有提示的。。IE6下应该会弹窗提示(没记错的话))
跨域AJAX请求的解决方案
在AJAX应用环境中,由于安全的原因,浏览器不允许XMLHttpRequest组件请求跨域资源。在很多情况下,这个限制给我来带来的诸多不便。很多同行,研究了各种各样的解决方案:
1. 通过修改document.domain和隐藏的IFrame来实现跨域请求。这种方案可能是最简单的一种跨域请求的方案,但是它同样是一种限制最大的方案。首先,它只能实现在同一个顶级域名下的跨域请求;另外,当在一个页面中还包含有其它的IFrame时,可能还会产生安全性异常,拒绝访问。
2.通过请求当前域的代理,由服务器代理去访问另一个域的资源。XMLHttpRequest通过请求本域内的一个服务器资源,将要访问的目标资源提供给服务器,交由服务器去代理访问目标资源。这种方案,可以实现完全的跨域访问,但是开发,请求过程的消费会比较大。
3. 通过HTML中可以请求跨域资源的标签引用来达到目的,比如Image,Script,LINK这些标签。在这些标签中,Script无疑是最合适的。在请求每一个脚本资源时,浏览器都会去解析并运行脚本文件内定义的函数,或需要马上执行的JavaScript代码,我们可以通过服务器返回一段脚本或 JSON对象,在浏览器解析执行,从而达到跨域请求的目的。使用script标签来实现跨域请求,只能使用get方法请求服务器资源。

第一个解决方案需要根域名是相同的,例如 a.domain.com和 b.domain.com。整个解决方案大概如下图所示:
AJAX的跨域与JSONP(为文章自动添加短址的功能) 
第二个解决方案就是在服务器端通过WebClient(或者其他)的类来请求跨域的内容,这里需要注意的一点是,如果你要将cookies信息也包含在WebClient的请求中的话,你需要手动的去将Cookies信息加到WebClient中去。

第三个解决方案就和我们下面需要说道的JSONP有关的。

JSONP
JSONP全称应该是“JSON with padding”吧,它正是利用了<script />可以跨域请求的特性。简单来说JSONP就是在客户端将要用来处理请求结果的函数名作为参数传递给服务器端,然服务器端将请求结果数据作为参数包装在这个函数中并返回给客户端执行。有点抽象?那么直接看图吧:
AJAX的跨域与JSONP(为文章自动添加短址的功能) 
下面来个实例讲解一下。这个实例就是为我们的博文自动生成一个短址的url,为了墙内的朋友方便,我们就直接使用国内的http://s8.hk提供的短址服务(API地址)。
我们试下

<script type="text/javascript"> 
$("#shortIt").click(function(){ 
c_url = 'http://s8.hk:8088/s8/s?format=text&longUrl='; 
c_url += document.location.href; 
$.get(c_url,function(data){ 
alert(data); 
}) 
}); 
</script>

测试下,什么?不可以?肯定不可以啦,因为是跨域嘛,所以我们需要利用<script />标签可以跨域请求的特性:
<script type="text/javascript"> 
function alertShortUrl(url){ 
alert(url); 
} 
$("#shortItByJSONP").click(function(){ 
c_url = 'http://s8.hk:8088/s8/s?format=text&longUrl='; 
c_url += document.location.href; 
//注意下面将函数名‘alertShortUrl'传进去咯 
c_url += '&jsonp=alertShortUrl' 
//生成一个<script />标签并添加到<head />中 
script = $('<script type="text/javascript" />') 
.attr('src', c_url); 
//这里为什么要用appendChild? 
//因为jQuery的append方法对<script/>已经做了处理 
//你也可以用$('head').append(script); 
//这里不用只是为了让你看得更清楚点而已。 
$('head')[0].appendChild(script[0]); 
}); 
</script>

哈哈,再点点测试按钮看看?很好,成功了。
其实不用这么麻烦,因为jQuery自从1.2版以后就已经添加了对JSONP的支持,你只需要给一个问号作为占位符就可以了,所以我们上面的代码可以写成:

<script type="text/javascript"> 
$("#shortItByjQueryJSONP").click(function(){ 
c_url = 'http://s8.hk:8088/s8/s?format=text&longUrl='; 
c_url += document.location.href; 
//注意下面只需一个问号,不用具体的函数名 
c_url += '&jsonp=?' 
//注意是getJSON 哦 
$.getJSON(c_url, function(data){ 
alert(data); 
}); 
}); 
</script>

哈哈,是不是很简便呢?下面就用这个实现为我们的文章添加自动缩短网址的功能吧:
<script type="text/javascript"> 
$(function(){ 
c_url = 'http://s8.hk:8088/s8/s?format=text&longUrl='; 
c_url += document.location.href; 
//注意下面只需一个问号,不用具体的函数名 
c_url += '&jsonp=?' 
$.getJSON(c_url, function(data){ 
//这里要这么处理、放到哪里就看你自己喜欢咯.而且这还和你博客使用的模板有关的哦 
$("<div>本文短址:</div>").css("font-weight", "normal") 
.css("font-size", "12px") 
.append($("<a>"+data+"</a>").attr("href", data)) 
.appendTo(".post .postTitle"); 
}); 
}); 
</script>

OK,打完收工。Enjoy it!
再多说几句,在twitter上很多还是用bit.ly、j.mp等国外的短址服务,墙得厉害,每次看不到很郁闷。尽量不要用那些墙得厉害的吧。
Javascript 相关文章推荐
JavaScript实现动态增加文件域表单
Feb 12 Javascript
在线编辑器中换行与内容自动提取
Apr 24 Javascript
对setInterval在火狐和chrome切换标签产生奇怪的效果之探索,与解决方案!
Oct 29 Javascript
js jquery分别实现动态的文件上传操作按钮的添加和删除
Jan 13 Javascript
利用jquery写的左右轮播图特效
Feb 12 Javascript
JavaScript中判断整字类型最简洁的实现方法
Nov 08 Javascript
jquery Easyui Datagrid实现批量操作(编辑,删除,添加)
Feb 20 Javascript
Vue 换肤的示例实践
Jan 23 Javascript
jQuery基于闭包实现的显示与隐藏div功能示例
Jun 09 jQuery
js实现小球在页面规定的区域运动
Jun 16 Javascript
如何配置vue.config.js 处理static文件夹下的静态文件
Jun 19 Javascript
在Vue中使用Echarts可视化库的完整步骤记录
Nov 18 Vue.js
前淘宝前端开发工程师阿当的PPT中有JS技术理念问题
Jan 15 #Javascript
20个非常有用的PHP类库 加速php开发
Jan 15 #Javascript
javascript 特性检测并非浏览器检测
Jan 15 #Javascript
javascript 构建一个xmlhttp对象池合理创建和使用xmlhttp对象
Jan 15 #Javascript
extjs 为某个事件设置拦截器
Jan 15 #Javascript
利用onresize使得div可以随着屏幕大小而自适应的代码
Jan 15 #Javascript
javascript 不间断的图片滚动并可点击
Jan 15 #Javascript
You might like
基于PHP CURL获取邮箱地址的详解
2013/06/03 PHP
PHP 只允许指定IP访问(允许*号通配符过滤IP)
2014/07/08 PHP
PHP网络操作函数汇总
2015/05/18 PHP
PHP之浮点数计算比较以及取整数不准确的解决办法
2015/07/29 PHP
PHP下载生成的csv文件及问题总结
2015/08/06 PHP
ThinkPHP中使用Ueditor富文本编辑器
2015/09/02 PHP
PHP编程入门的基本语法知识点总结
2016/01/26 PHP
PHP图片水印类的封装
2017/07/06 PHP
解决php用mysql方式连接数据库出现Deprecated报错问题
2019/12/25 PHP
JavaScript加密解密7种方法总结分析
2007/10/07 Javascript
jQuery JSON的解析方式分享
2011/04/05 Javascript
Jquery each方法跳出循环,并获取返回值(实例讲解)
2013/12/12 Javascript
jquery中$each()方法的使用指南
2015/04/30 Javascript
js实现仿爱微网两级导航菜单效果代码
2015/08/31 Javascript
纯JS实现可拖拽表单的简单实例
2016/09/02 Javascript
深入理解jquery中extend的实现
2016/12/22 Javascript
ng-options和ng-checked在表单中的高级运用(推荐)
2017/01/21 Javascript
Angularjs 动态添加指令并绑定事件的方法
2017/04/13 Javascript
vue绑定的点击事件阻止冒泡的实例
2018/02/08 Javascript
Vue使用高德地图搭建实时公交应用功能(地图 + 附近站点+线路详情 + 输入提示+换乘详情)
2018/05/16 Javascript
js实现敏感词过滤算法及实现逻辑
2018/07/24 Javascript
微信小程序云开发如何使用npm安装依赖
2019/05/18 Javascript
Postman动态获取返回值过程详解
2020/06/30 Javascript
vue v-on:click传递动态参数的步骤
2020/09/11 Javascript
[03:53]2016国际邀请赛中国区预选赛第三日TOP10精彩集锦
2016/06/29 DOTA
[02:38]DOTA2亚洲邀请赛小组赛精彩集锦:Wings完美团击溃对手
2017/03/29 DOTA
Python中操作MySQL入门实例
2015/02/08 Python
Anaconda配置pytorch-gpu虚拟环境的图文教程
2020/04/16 Python
Python通过kerberos安全认证操作kafka方式
2020/06/06 Python
基于opencv的selenium滑动验证码的实现
2020/07/24 Python
浅析HTML5 Landmark
2020/09/11 HTML / CSS
单位授权委托书范文
2014/08/02 职场文书
追讨欠款律师函
2015/05/27 职场文书
初三化学教学反思
2016/02/22 职场文书
php随机生成验证码,php随机生成数字,php随机生成数字加字母!
2021/04/01 PHP
Feign调用传输文件异常的解决
2021/06/24 Java/Android