JS跨域知识整理
在“跨域”一词经常性地出现以前,我们其实已经频繁地使用它了。如在A网站的img,src指向B网站的某一图片地址,毫无疑问,这在通常情况下都是能正常显示的(且不论防盗链技术);同样,可以使script标签的src属性指向其它网站的脚本资源(在某些情况下甚至鼓励这样做,以便充分利用其它网站的负载优势,减小自身服务器的并发量)。然而,如若使用js去主动请求其它网站的数据,比如ajax方式,就会遇到让人郁闷的跨域问题,这也是我们平常所说的跨域。由于安全原因,跨域访问是被各大浏览器所默认禁止的。这里涉及到同源策略的概念:同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的 URL 的域必须与当前 Web 页面的域相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。
跨域带来的具体安全问题博主没有深究,大伙可以自行脑补。
然而,很多情况下,特别是在互联网持续发展的今天,我们需要请求来自不同合作伙伴或数据提供商的前端接口,在跨域访问的方式没有规范化前(client端跨域访问的需求看来也引起w3c的注意了,看资料说html5 WebSocket标准支持跨域的数据交换,应该也是一个将来可选的跨域数据交换的解决方案),有什么方法能绕过它的限制呢?答案有很多(虽然都很麻烦),最常用的当属所谓的JSONP跨域了。
JSONP原理
JSONP的最基本的原理是:动态添加一个<script>标签,而script标签的src属性是没有跨域的限制的。这样说来,这种跨域方式其实与ajax XmlHttpRequest协议无关了。
JSONP即JSON with Padding。由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源。如果要进行跨域请求, 我们可以通过使用html的script标记来进行跨域请求,并在响应中返回要执行的script代码。 这种跨域的通讯方式称为JSONP。
来个简单的例子:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Test Jsonp</title>
<script type="text/javascript">
function jsonpCallback(result)
{
alert(result.msg);
}
</script>
<script type="text/javascript" src="http://crossdomain.com/jsonServerResponse?jsonp=jsonpCallback"></script>
</head>
<body>
</body>
</html>
简述原理与过程:首先在客户端注册一个callback, 然后把callback的名字传给服务器(这里客户端和服务器约定以key为jsonp的查询字符串值传递)。此时,服务器先生成 json 数据。 然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp。最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。客户端浏览器,解析script标签,并执行返回的 javascript 文档,即执行了预定义的callback函数。
从上述简述可以推出:除了返回函数形式的js代码片段,服务端自然能返回所有符合规范的可执行js片段。
JSONP的缺点是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。(下面还有)
jQuery的Jsonp
如前所述,jsonp并非ajax请求,但是jQuery仍提供与jQuery.ajax一致的方式进行跨域请求:
$.ajax({
url: 'http://crossdomain.com/jsonServerResponse',
type: 'GET',
dataType: 'jsonp',
jsonp: "callback",
jsonpCallback: 'functionName',
success: function (data, textStatus, jqXHR) { }
//……
});
如上所示,dataType设为jsonp表示这是一次跨域请求,jsonp设为服务端预定的传递函数名称的查询字符串key,而jsonpCallback即为js函数名称;假如jsonpCallback不设置,那么jQuery将自动生成的随机函数名(在window对象中加载一个全局的函数,当代码插入时函数执行,执行完毕后就会被移除),可推断该自动生成的函数会回调上述代码中的success函数。(当手动为jsonpCallback赋值时,不知道success函数会否回调,还是说jQuery会寻找预定义的函数,若找不到则报错?博主懒,以后再试吧。)当然jQuery为我们提供了一个简易版本,$.getJSON,这里就不赘述了。
需要注意的是success函数中的jqXHR参数,在ajax请求中,它是正宗的jqXHR对象,亦可看作是XMLHTTPRequest对象(继承or封装),但是在jsonp请求中却并非如此,几乎不能带给我们如XMLHTTPRequest中最有用的那些信息:它缺少XMLHTTPRequest的请求状态信息,所以并不能触发绝大部分的回调函数,比如error、complete等(jQuery1.9.0),而可以被回调的success函数推测应该是由script标记的load事件触发,这也同ajax依靠XMLHTTPRequest的状态的机制完全不同。经试验,脱胎于jQuery的zepto(v1.1.3),在jsonp请求出现错误,比如加载js文档时头部返回401错误时,error函数会执行,但是该函数的jqXHR参数也同样不是正宗的jqXHR类型,甚至不能通过它获取响应的头部信息,在这种情况下,我们只是被告知某个环节出错了,却并不知道具体的错误信息。类似响应头承载有用信息的场景,博主不建议使用jsonp,可以说,使用jsonp的一个前提是:除了网络异常等非业务异常外,所有业务异常(概括地说,乃是从服务器接收请求到返回响应这段时间内抛出的所有异常)都需要以请求结果的形式直接返回给客户端,便于客户端回调分析。
参考资料:
转载请注明本文出处:http://www.cnblogs.com/newton/p/3930474.html
JS跨域知识整理的更多相关文章
- Javascript 跨域知识详细介绍
JS跨域知识总结: 在“跨域”一词经常性地出现以前,我们其实已经频繁地使用它了.如在A网站的img,src指向B网站的某一图片地址,毫无疑问,这在通常情况下都是能正常显示的(且不论防盗链技术):同样, ...
- 前端Js跨域方法汇总—剪不断,理还乱,是跨域
1.通过jsonp跨域2.通过修改document.domain来跨子域(iframe)3.隐藏的iframe+window.name跨域4.iframe+跨文档消息传递(XDM)5.跨域资源共享 C ...
- js跨域调用mvc ActionResult扩展
背景 最近2个项目中都用到了js跨域访问的知识,2个项目都需要主站与各个分站之间进行数据交互.状态同步等相关操作.浏览器本身是不允许进行跨域访问,在MVC中我们可以扩展一个方法来实现这个功能.在此大家 ...
- js跨域请求数据的3种常用的方法
由于js同源策略的影响,当在某一域名下请求其他域名,或者同一域名,不同端口下的url时,就会变成不被允许的跨域请求.那这个时候通常怎么解决呢,对此菜鸟光头我稍作了整理:1.JavaScript 在 ...
- [记录]js跨域调用mvc ActionResult扩展
背景 最近2个项目中都用到了js跨域访问的知识,2个项目都需要主站与各个分站之间进行数据交互.状态同步等相关操作.浏览器本身是不允许进行跨域访问,在MVC中我们可以扩展一个方法来实现这个功能.在此大家 ...
- pdf.js跨域加载文件
pdf.js一个基于Html的工具类,熟悉pdf.js的朋友们很清楚,pdf.js帮助我们做了很多事.尤其金融类网站会产生很多的报表.需要在线预览.pdf.js绝对是我们的首选 本地预览 在pdf.j ...
- 5种处理js跨域问题方法汇总(转载)
1.JSONP跨域GET请求 ajax请求,dataType为jsonp.这种形式需要请求在服务端调整为返回callback([json-object])的形式.如果服务端返回的是普通json对象.那 ...
- JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...
- 【js跨域】js实现跨域访问的几种方式
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...
随机推荐
- IOS演变史
我是从iOS5开始接触iPhone操作系统,对此系统也算是有爱有恨,今天从网上整理以下整个iOS发展的历史,了解了解也算做以后闲时讨论的一个话题. 电脑需要操作系统,手机也需要,2007年,苹果带着旗 ...
- 《Java中方法的重写》
//方法的重写 /* 注意:方法的重写要遵循“两同两小一大”规则 “两同”即方法名相同.形参列表相同: “两小”(1)指的是子类方法返回值类型比父类方法的返回值类型更小或相等,[什么意思?] (2)子 ...
- NSAssert的使用
NSAssert的使用 苹果在foundation.framework中定义了这么一个宏: #define NSAssert(condition, desc, ...) 第一个参数为一个条件判 ...
- 解决Only a type can be imported. com.mysql.jdbc.Connection resolves to a package的报错问题
写jsp加载数据驱动以后老是提示Only a type can be imported. com.mysql.jdbc.Connection resolves to a package的错误,然而改成 ...
- Eclipse for php + Xdebug搭建PHP的调试环境
Xdebug安装教程 下载Xdebug 首先我们需要下载Xdebug,务必根据安装的PHP版本,选择合适的Xdebug版本,由于我是在Windows环境下安装PHP的,所以选择下载Windows版本的 ...
- 带优先级的队列 - PHP实现
很久以前写的一个功能,当时需要一个优先级的队列,特用新学的swoole写了一个简单的demo,仅满足当时的需求. 功能说明: 完全参考httpsqs增加优先级参数level 例: ...
- Android 学习第3课,小例子
package temperature.convert; import java.util.Scanner; public class Converter { public static void m ...
- Largest Number
Given a list of non negative integers, arrange them such that they form the largest number. For exam ...
- 问:Linux下Chrome标题栏中文乱码
From:http://blog.csdn.net/loveaborn/article/details/29579787 在使用Linux的时候你会遇到一些奇奇怪怪的问题,不过,你会在解决这些问题的过 ...
- python数据结构与算法——图的最短路径(Dijkstra算法)
# Dijkstra算法——通过边实现松弛 # 指定一个点到其他各顶点的路径——单源最短路径 # 初始化图参数 G = {1:{1:0, 2:1, 3:12}, 2:{2:0, 3:9, 4:3}, ...