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的一个前提是:除了网络异常等非业务异常外,所有业务异常(概括地说,乃是从服务器接收请求到返回响应这段时间内抛出的所有异常)都需要以请求结果的形式直接返回给客户端,便于客户端回调分析。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Javascript 跨域知识详细介绍的更多相关文章

  1. javascript 跨域请求详细分析(终极跨域解决办法)

    自从我接触前端以来,接手的项目里面很大部分都是前后端分离的,后端只提供接口,前端根据后端接口渲染出实际页面.个人觉得这是一个挺好的模式,前后端各自负责各自的模块,分工明确,而且也给前端更大的发挥空间. ...

  2. JavaScript 跨域漫游

    前言: 最近在公司做了几个项目都涉及到了iframe,也就是在这些iframe多次嵌套的项目中,我发现之前对iframe的认识还是比较不足的,所以就静下心来,好好整理总结了iframe的相关知识:&l ...

  3. javascript跨域訪问探索之旅

    需求:         近期工作负责一个互联网应用A(我公司应用)与还有一个互联网应用B进行通讯.通讯的方式是这种:还有一个互联网应用某些表单信息须要从我公司的互联网应用获取.首先用户訪问互联网应用B ...

  4. 优雅绝妙的Javascript跨域问题解决方案

    关于Javascript跨域问题的解决方案已在之前的一片文章中详细说明,详见:http://blog.csdn.net/sfdev/archive/2009/02/13/3887006.aspx: 除 ...

  5. JavaScript 跨域:window.postMessage 实现跨域通信

    JavaScript 跨域方式实现方式有很多,之前,一篇文章中提到了 JSONP 形式实现跨域.本文将介绍 HTML5 新增的 api 实现跨域:window.postMessage . 1 othe ...

  6. jQuery(三) javascript跨域问题(JSONP解决)

    加油~ --WH 一.什么是javascript跨域问题? 域:服务器域名,唯一标识(协议,域名,端口)必须保证一致,说明域相同 跨域:在一个服务器上,去访问另一个服务器上,并且得到另一个服务器返回回 ...

  7. JavaScript跨域解决方式

    平时工作中经常被JavaScript跨域问题所困扰,其实有很多种解决方式,下面给大家介绍常用的几种: 1.jsonp解决跨域问题 客户端代码: <!DOCTYPE html> <ht ...

  8. 利用javascript跨域访问cookie之广告推广

    在上一篇<说一说javascript跨域和jsonp>中,利用JSONP进行了跨域的数据访问,利用JS本身的跨域能力在远端生成HTML结构的方式完成了一个小广告. 在实际应用中, 跨域使用 ...

  9. Javascript跨域问题总结

    疯狂的JSONP 关于JSON与JSONP简单总结 window.name实现的跨域数据传输 JavaScript跨域总结与解决办法 flash跨域策略文件crossdomain.xml配置详解

随机推荐

  1. PHP删除当前目录及其目录下的所有文件

    使用PHP遍历一个目录下的所有目录及文件,并删除该目录及其目录下的所有子目录和文件,本次代码通过递归的方式来实现. 用到的函数: scandir($path) 遍历一个目录下所有文件并返回数组. un ...

  2. MySQL-8.0.11 在 Windows10 上的安装

    下载 MySQL8.0 For Windows zip包下载地址:https://dev.mysql.com/downloads/file/?id=476233. 进入页面后可以不登录,点击底部“No ...

  3. hdf 5文件格式及python中利用h5py模块读写h5文件

    h5文件格式,HDF 的版本 5(HDF 版本 5不与 HDF 版本 4 及早期版本兼容).HDF是什么呢?就是Hierarchical Data Format,可以存储不同类型的图像和数码数据的文件 ...

  4. spark面试总结3

    Spark core面试篇03 1.Spark使用parquet文件存储格式能带来哪些好处? 1) 如果说HDFS 是大数据时代分布式文件系统首选标准,那么parquet则是整个大数据时代文件存储格式 ...

  5. dedecms中arclist标签做分页以及分页点击模块样式错乱问题

    in 使用织梦建站,通常会调用到一个文章列表,dedecms官网list标签没有提供typeid的属性,首页或多列表部分情况下使用分页并不方便,这就需要用arclist标签实现一个分页功能:以下还是展 ...

  6. SpringDataJPA与Mybatis的优异性

    首先表达个人观点,JPA必然是首选的. 个人认为仅仅讨论两者使用起来有何区别,何者更加方便,不足以真正的比较这两个框架.要评判出更加优秀的方案,我觉得可以从软件设计的角度来评判.个人对 mybatis ...

  7. 基于FineUIMVC的代码生成器(传统三层)v1.0

    三层我就不说了,主要是看框架思路可扩展.以前用FineUI开源版写过一版,修修改改自己用了,没有特意的整理,FineUIMVC开发还是比较快,移植了一下两天就弄完了,算是一个对新手有用的工具,先放出第 ...

  8. Java基础系列--包装类

    原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/5462489.html 1.8种基本数据类型都有各自的包装类,其对应关系为: 基本—————— ...

  9. More Effective C# 【前戏】

    买了很多很多书,想到就买,觉得有需要就买.买书的情况是不一样的:有时候,买的时候还是比较空,买来之后工作开始忙起来了,就没怎么看:有时候,买的时候比较忙,忙的乱了方寸,觉得有必要找本书来静心一下.不过 ...

  10. 微信小程序--帮助选择困难症者

    用户登录小程序成功后,通过传来的code获取openid,后端用的是PHP //获取code值换取openid public function code_weixin(Request $request ...