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跨域没有问题

最新文章

  1. xamarin android ListView手动分组
  2. SQL知识整理一:触发器、存储过程、表变量、临时表
  3. js 常见混乱
  4. BZOJ3485 : [Baltic2012]peaks
  5. js 去掉input标签中的百分号【%】
  6. 实现ScrollView中包含ListView,动态设置ListView的高度
  7. Windows Azure 设置虚拟机静态外网IP地址
  8. Jquery post 传递数组给asp.net mvc方法
  9. js限制文本框只能输入数字
  10. 秒杀多线程第二篇 多线程第一次亲热接触 CreateThread与_beginthreadex本质差别
  11. JavaScript闭包的一些理解
  12. js 关键字 in
  13. BI服务器配置与客户端情况
  14. 牛客网小a的旅行计划
  15. jQuery 方式模拟提交表单
  16. Logstash Introduction
  17. tensorflow的save和restore
  18. canvas制作完美适配分享海报
  19. HQL中的Like查询需要注意的地方
  20. 鸟哥私房菜vim常用命令

热门文章

  1. xcode8.3 shell 自动打包脚本 记录
  2. 一天搞定HTML----标签类型与类型转换05
  3. Java中设计模式之生产者消费者模式-4
  4. javaSE_07Java中类和对象-封装特性--练习
  5. Mavnen的几种依赖关系
  6. D语言需要大公司支持
  7. SQL Server使用导入导出向导导入超过4000个字符的字段的数据
  8. web 直播&amp;即时聊天------阿里云、融云(三)
  9. Ajax请求,跨域小坑
  10. 日常踩坑 searter