URL  说明 是否允许通信
http://www.a.com/a.js

http://www.a.com/b.js
同一域名下 允许
http://www.a.com/lab/a.js

http://www.a.com/script/b.js
同一域名下不同文件夹 允许
http://www.a.com:8000/a.js

http://www.a.com/b.js
同一域名,不同端口 不允许
http://www.a.com/a.js

https://www.a.com/b.js
同一域名,不同协议 不允许
http://www.a.com/a.js

http://70.32.92.74/b.js
域名和域名对应ip 不允许
http://www.a.com/a.js

http://script.a.com/b.js
主域相同,子域不同 不允许
http://www.a.com/a.js

http://a.com/b.js
同一域名,不同二级域名(同上) 不允许(cookie这种情况下也不允许访问)
http://www.cnblogs.com/a.js

http://www.a.com/b.js
不同域名 不允许

这张表上已经说清楚了哪些情况允许通信,哪些不允许通信。

我们现在要解决的问题是将这些不允许变为允许。。。

JS跨域

1、为什么会有跨域?

简单的来说,在发送ajax请求的时候会遇到js跨域

大家都知道,发送ajax的时候会用到XMLHttpRequest这个对象,但是为了安全,浏览器对象做出了限制,不允许上表中的不允许情况通信。。。

所以,只要不使用XMLHttpRequest对象发送ajax请求,就不会出现跨域限制的问题。

2、不使用ajax发送请求,但是要达到局部刷新的效果怎么办?

假设请求的网页为本地的1.html

    1. <html>
    2. <head>
    3. </head>
    4. <body>
    5. </body>
    6. </html>

动态加载js

  1. var script = document.createElement("script");
  2. script.type = "text/javascript";
  3. script.src = "http://bbb.com";
  4. var head = document.getElementsByTagName("head")[0];
  5. head.insertBefore(script, head.firstChild);

这段代码执行完成后,会在head标签中加入http://bbb.com这个地址的响应内容,例:

如果http://bbb.com这个地址返回的是字符串123,那么当前调用页面的结果即为

<html>

<head>

<script src="http://bbb.com" type="text/JavaScript">

123

</script>

</head>

<body>

</body>

</html>

如果http://bbb.com这个地址返回的是test("ccc"),那么当前调用页面的结果即为

<html>

<head>

<script src="http://bbb.com" type="text/javascript">

test("ccc");

</script>

</head>

<body>

</body>

</html>

看到这里应该就明白了,其实这段动态加载js的代码只是把另一个页面的内容加载到本页面了

现在这个页面运行的时候会报错,缺少test方法,因为没有定义test就调用了,我们在本地的1.html加入test方法

    1. <html>
    2. <head>
    3. <script>
    4. function test(a){
    5. console.log(a);
    6. }
    7. var script = document.createElement("script");
    8. script.type = "text/javascript";
    9. script.src = "http://bbb.com";
    10. var head = document.getElementsByTagName("head")[0];
    11. head.insertBefore(script, head.firstChild);
    12. </script>
    13. </head>
    14. <body>
    15. </body>
    16. </html>

好了,1.html就是最终的样子,执行的顺序是:

1.先初始化test方法

2.创建script标签,加载http://bbb.com的内容,将返回结果插入到head标签

3.返回结果是test("ccc") 调用了test方法,就打印出来ccc了

3.能否不使用动态创建script的方式呢,怎么感觉没用?

完全可以。

    1. <html>
    2. <head>
    3. <script>
    4. function test(a){
    5. console.log(a);
    6. }
    7. </script>
    8. <script src="http://bbb.com" type="text/javascript" ></script>
    9. </head>
    10. <body>
    11. </body>
    12. </html>

这么写效果是一样的,并不是说一定要动态加载script标签才是跨域,这里是一个误区哦~

那为什么要使用动态加载script标签呢?

原因有两个:

1.src动态改变,不用写死。

2.异步加载。如果src需要加载的内容返回结果较慢,动态创建script标签是异步加载的不会出现阻塞。

js的跨域已经说清楚了吧,下面我们来看下jQuery的跨域

jquery跨域

大家都知道jquery 是 js写的,所以不用看源码也知道它的原理就是我们上面说的js的跨域原理
我们主要说下$.ajax ,用过jquery的同学肯定都用过这个方法,封装的很好,用起来很方便
jquery1.2的时候加入了jsonp这个参数类型来支持jquery的跨域,例:

$.ajax({

        url: "http://bbb.com",

        type: "get",

        data:{p1:1,p2:2},

        dataType: "jsonp",

        jsonp: "callback",

        success: function(aaa) {

             console.log(aaa);

        }

    });

只需要在正常的ajax代码中写上红色的内容,就可以完成跨域的ajax请求了。是不是使用起来很方便O(∩_∩)O~
 

js跨域和jquery跨域有什么优缺点?


jquery已经将所有的调用封装成对象,调用起来很方便
js跨域写起来比较麻烦,尤其是传递参数的时候,需要手动拼接data ?&p1=1&p2=2
但是jquery的跨域有个bug,当同时发出大量请求瞬间返回结果时,会导致接收请求的时候丢失部分回调请求(实际上已经发送成功了)
例:


这种情况很常见,就是循环发送ajax请求么。

非跨域请求这么写没有问题,success会被调用100次,但是当dataType : "jsonp"时,success可能只会执行70次80次,剩下的请求没有成功也没有失败,用complete也抓不到。
浏览器会报错找不到callback,或无任何提示。有两个地方会引起这种问题
  1. // Clean-up function
  2. jqXHR.always(function() {
  3. // Set callback back to previous value
  4. window[ jsonpCallback ] = previous;
  5. // Call if it was a function and we have a response
  6. if ( responseContainer && jQuery.isFunction( previous ) ) {
  7. window[ jsonpCallback ]( responseContainer[ 0 ] );
  8. }
  9. });

1.callback被清除,所以有时候会报出找不到callback这个方法

2.xmlHttp.readyState==4  同时发送请求的时候,浏览器的状态只有这么一个readyState当浏览器知道已经获取返回结果了,就不接收请求了
这个肯定是jquery的bug,使用js跨域没有问题

js&jquery跨域详解jsonp,jquery并发大量请求丢失回调bug的更多相关文章

  1. 跨域详解之jsonp,底层的实现原理

    分享一下跨域,不仅是因为现在的工作中遇到的越来越多,而且在面试中也经常被问到. 那么什么是跨域呢,我们来看官方给出的解释:浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的(所谓同源是指,域名 ...

  2. 跨域详解之-----Jsonp跨域

    一.通过jsonp跨域 在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的.但是,在页面上引入不同域上的js脚本文件却是可以的,jsonp正是利用这个特性来实现的. 比如 ...

  3. ajax工作原理及jsonp跨域详解

    一.Ajax简介 ajax = 异步 JavaScript 和 XML. ajax是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术.我们知道,传统的网页(不使用ajax)如果需要更新内容, ...

  4. js跨域详解

    跨域概念:Cross-origin resource sharing

  5. 纯 js 实现跨域接口调用 jsonp

    开发「bufpay.com 个人即时到账收款平台」的时候,支付页面需要 poll轮询 查询订单状态. bufpay 支付接口如下: 接口地址:https://bufpay.com/api/pay/ai ...

  6. 【nginx】nginx解决跨域详解

    使用场景:本地运行一个项目,但是要访问外域的api接口,存在跨域问题,解决方式有很多,但我尝试用nginx解决,搜索了网上文章后再加上尝试终于成功, 其中一些注意事项和大家分享一下. 一.window ...

  7. JavaScript中的跨域详解(二)

    4.AJAX 同源政策规定,AJAX请求只能发给同源的网址,否则就报错. 除了架设服务器代理(浏览器请求同源服务器,再由后者请求外部服务),有三种方法规避这个限制. JSONP WebSocket C ...

  8. JavaScript中的跨域详解(一)

    同源策略 所谓的同源策略,指的是浏览器对不同源的脚本或者文本访问方式进行的限制. 所谓同源,就是指两个页面具有相同的协议,主机(也常说域名),端口,三个要素缺一不可. 同源政策的目的,是为了保证用户信 ...

  9. JS JSOP跨域请求实例详解

    JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题.这篇文章主要介绍了JS JSOP跨域请求实例详解的相关资料,需要的朋友可以参考下 ...

随机推荐

  1. angularjs 水平滚动选中按钮高亮显示 swiper和回到顶部指令的实现ionic

    首先安装 swiper npm install --save swiper 或者 bower install --save swiper <link rel="stylesheet&q ...

  2. [深圳/广州]微软SQL技术沙龙分享会(MVP)

    [深圳/广州] 新一期俱乐部活动报名开始,这次是广深地区SQL Server 技术沙龙分享会(MVP),SQL Server作为一个数据平台,不管是SQL Server 2017 on Linux 还 ...

  3. CRL快速开发框架4.4版发布,支持主从读写分离

    经过一些调整和优化,4.3已经运行在生产环境,对于不久将会遇到的查询性能,读写分离需求列上日程 读写分离需求 对于一个数据库作了主从发布/订阅,主库为DB1,从库为DB2 所有写入通过DB1,所有查询 ...

  4. Java中常见的数据结构的区别

    把多个数据按照一定的存储方式,存储起来,称存储方式之为数据结构. 数据的存储方式有很多,数组,队列,链表,栈,哈希表等等. 不同的数据结构,性能是不一样的,比如有的插入比较快,查询比较快,但是删除比较 ...

  5. 定位--position属性

    一.定位--position属性 1.static:默认值 没有定位--以标准文档流方式显示 2.relative:相对定位--相对自身原来的位置进行偏移(top left right bottom) ...

  6. div+css的属性

    div+css的属性 gCascading Style Sheet 层叠式样式表 ==> 层叠样式表 Internal Style Sheet 内部样式表 External Style Shee ...

  7. javaCV开发详解之4:转流器实现(也可作为本地收流器、推流器,新增添加图片及文字水印,视频图像帧保存),实现rtsp/rtmp/本地文件转发到rtmp流媒体服务器(基于javaCV-FFMPEG)

    javaCV系列文章: javacv开发详解之1:调用本机摄像头视频 javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG.j ...

  8. 类型转换之 PropertyEditorSupport类

    这个类可以用于自定义的类型转换, 子类继承这个类之后可以重写子类的方法 ,其中比较重要的是setAsText和setValue方法,setAsText 子自己的方式处理转换,setValue将转换的结 ...

  9. Linux下SVN+多个Tomcat自动部署

    项目中都是jsp开发,所以用到Tomcat. 在我文章中也写过多个Tomcat 的部署,具体可以参考:http://www.cnblogs.com/magmell/p/7045193.html SVN ...

  10. Swift区间运算符

    Swift 提供了两个方便表达一个区间的值的运算符. 闭区间运算符 闭区间运算符(a...b)定义一个包含从a到b(包括a和b)的所有值的区间. ‌ 闭区间运算符在迭代一个区间的所有值时是非常有用的, ...