什么是跨域?为什么要实现跨域呢?

 
这是因为JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。也就是说只能访问同一个域中的资源。我觉得这就有必要了解下javascript中的同源策略是怎么回事了:javascript的同源策略
 
于是当我们想某些特定的功能的时候,实现合理的跨域请求就显得比较重要了。
 
 
 
-->1.原生Ajax对象xhr的跨域
 
-->2.简单jsonp
 
-->3.图像Ping
 
-->4.document.domain+iframe实现跨域
 
 
 
javascript中的原生Ajax对象XMLHTTPRequest
 
先看原生ajax的实现代码:
 
复制代码
 1       var xhr = createXHR();//for IE封装一下浏览器不同的ajax对象
 2       xhr.onload = function(event){ //确保接收到适当的响应
 3         if((xhr.status >=200&&xhr.status<300)||xhr.status == 304){
 4           alert(xhr.responseText);
 5         }else{
 6           alert('error:'+xhr.status);
 7         }
 8       }
 9       xhr.open('get','**.php',true);//open方法的参数open(get/post,url,是否发送异步请求)
10       xhr.send(null);//open只是启动一个请求,并未发送,调用send()才会发送请求
复制代码
我们知道想上面这样就可以发送ajax请求啦,得到的响应数据会自动填充xhr对象的属性,我们就可以去访问啦。
 
但是,就是有上面说到的限制,只能想同一个域中使用相同端口和协议的URL发送请求。然后就是解决跨域的问题了。
 
好在有个东西叫CORS(跨源资源共享),它背后的思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。
 
实现方法:
 
1.发送get/post请求时,给它添加一个额外的Origin头部,其中包含请求页面的源信息(协议,域名和端口),以便服务器根据这个头部信息来决定是否响应,像这样的:  
 
Origin:http://www.nczonline.net
2.如果服务器认为这个请求可以接受,就在头部发回相同的源信息:
 
Access-Control-Allow-Origin:http://www.nczonline.net
如果没有这个头部或者源信息不匹配,那么服务器就会驳回请求,正常的情况下浏览器会处理请求。
 
深入研究CORS:HTTP access control (CORS)
 
另外,说到HTTP头部相关,我觉得也有必要了解下通常的Request Headers和Response Headers通常都有哪些参数,它们会告诉我们很多信息的:
 
 
 
 
 
之所以想到了解,是因为记得看过这篇文章,小胡子利用了响应头部的Date来实现了个倒计时:利用XMLHttpRequest响应头的Date实现倒计时
 
 
 
 
 
JSONP(双向)
 
     1、什么是JSONP:
 
          jsonp(json with padding),jsonp与json看起来差不多,只不过jsonp是被包含在函数调用中的json。jsonp由两部分组成,一部分是回调函数,一部分是数据。回调函数就是当响应到来时应该在页面中调用的函数,数据就是传入回调函数中的json数据。他的优点是:第一,他能直接访问响应文本;第二,jsonp支持在浏览器与服务器之间的双向通信。但同时也存在缺点:它无法保证加载的来自其他域的代码是安全的,还有就是无法判断jsonp的请求是否失败。 
 
     2、使用方法:
 
   动态创建<script>节点:
 
复制代码
1 function handleResponse(response){
2          alert("你的ip地址:"+response.ip+",ip地址所在的城市:"+response.city+",所在省份:"+response.region_name);
4       }
6       var script = document.createElement('script');
7       script.src = 'http://freegeoip.net/json/?callback=handleResponse';/*http://freegeoip.net是一个jsonp地理定位服务*/ 
8 document.body.insertBefore(script,document.body.firstChild);
复制代码
但是如何判断script节点加载完毕是个问题:ie只能通过script的readystatechange属性,其他浏览器支持script的load事件。
 
如果用了jquery的话,就不用写上面那些代码了,jquery做了很多工作,调用$.ajax()方法的时候,如果想使用jsonp这种方法,封装参数即可了。
 
移步这里查看详细:jQuery中的$.ajax()方法使用jsonp
 
 
 
图像ping(单向)
 
    1、什么是图像ping:
 
        图像ping是与服务器进行简单、单向的跨域通信的一种方式,请求的数据是通过查询字符串的形式发送的,而相应可以是任意内容,但通常是像素图或204相应(No Content)。 图像ping有两个主要缺点:首先就是只能发送get请求,其次就是无法访问服务器的响应文本。
 
   2、使用方法:
 
复制代码
1       var img = new Image();
2       img.onload = img.onerror = function(){
3          alert("done!");
4       };
5       img.src = "https://raw.githubusercontent.com/zhangmengxue/Todo-List/master/me.jpg";
6       document.body.insertBefore(img,document.body.firstChild);
复制代码
然后页面上就可以显示我放在我的github上某个地方的照片啦。
 
与<img>类似的可以跨域内嵌资源的还有:
 
(1)<script src=""></script>标签嵌入跨域脚本。语法错误信息只能在同源脚本中捕捉到。上面jsonp也用到了呢。
 
(2) <link src="">标签嵌入CSS。由于CSS的松散的语法规则,CSS的跨域需要一个设置正确的Content-Type消息头。不同浏览器有不同的限制: IE, Firefox, Chrome, Safari (跳至CVE-2010-0051)部分 和 Opera。
 
(3)<video> 和 <audio>嵌入多媒体资源。
 
(4)<object>, <embed> 和 <applet>的插件。
 
(5)@font-face引入的字体。一些浏览器允许跨域字体( cross-origin fonts),一些需要同源字体(same-origin fonts)。
 
(6) <frame> 和 <iframe>载入的任何资源。站点可以使用X-Frame-Options消息头来阻止这种形式的跨域交互。
 
 
 
 
 
document.domain+iframe实现跨域
 
首先要知道,只是在页面上通过<iframe>载入了资源,是不能与他交互的,像我的博客右边的那个About中的那个Github的Fllow一样的,只能去访问。那我们想要实现交互的话,对于主域相同而子域不同的情景,就可以借助于document.domain来实现。
 
www.one.com上的a.html
 
复制代码
 1       document.domain = 'a.com';
 2       var ifr = document.createElement('iframe');
 3       ifr.src = 'http://script.a.com/b.html';
 4       ifr.style.display = 'none';
 5       document.body.appendChild(ifr);
 6       ifr.onload = function(){
 7           var doc = ifr.contentDocument || ifr.contentWindow.document;
 8           // 在这里操纵b.html
 9           alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
10       };
复制代码
w3w.one.com上的b.html:
 
document.domain = 'a.com';
这种方式就可以实现a页面和b页面交互了。适用于{www.kuqin.com, kuqin.com, script.kuqin.com, css.kuqin.com}这样的域名下的页面间,这里默认他们使用相同的协议和端口。
 
 备注:某一页面的domain默认等于window.location.hostname。主域名是不带www的域名,例如a.com,主域名前面带前缀的通常都为二级域名或多级域名,例如www.a.com其实是二级域名。 domain只能设置为主域名,不可以在b.a.com中将domain设置为c.a.com。
 
同时在修改document.domain的时候也需要注意一些问题,和可能产生的影响:修改document.domain可能产生的影响
 
这部分参考了这里:js中跨域问题总结document.domain+iframe部分
 
 
 
这里说到了document.domain,那么我也就想到了document的其他属性,放这一起看下:
 
(1)document.referrer  简单来说,一般情况下浏览器请求A时发送的Header中Referer是什么,那么拿到A页面后document.referre的值就是什么.我们可以通过访问document的这个属性来知道我们的页面是从哪里来的。通常还能看到一些参数。
 
(2)document.links  它能得到页面中所有<a>和<area>标签中的href属性值。
 
(3)document.compatMode 如果得到的值是CSS1Compat那么是标准模式,BackCompat则是混杂模式
 
(4)document.readyState 文档加载属性 值为complete即加载完全 loading则正在加载。
 
上面只举例列了一些,其实还有很多很好用的,可以自行查阅手册:document的属性和方法
 
后面第二部分待总结的有:
 
-->5.利用iframe和location.hash
 
-->6.window.name跨域实现
 
-->7.HTML5 postMessage实现跨域

js中各种跨域问题实战小结的更多相关文章

  1. js中各种跨域问题实战小结(二)

    这里接上篇:js中各种跨域问题实战小结(一) 后面继续学习的过程中,对上面第一篇有稍作休整.下面继续第二部分: -->5.利用iframe和location.hash -->6.windo ...

  2. js中各种跨域问题实战小结(一)

    什么是跨域?为什么要实现跨域呢? 这是因为JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.也就是说只能访问同一个域中的资源.我觉得这就有必要了解下javascript中的同源策略 ...

  3. JS中实现跨域的方法总结

    今天早上在地铁看了点基础知识的考察题,看到了一个JS跨域的问题,仔细想了想自己脑子里竟然只剩下jsonp跨域和用nginx反向代理进行跨域,想着还有别的几种方法,就是想不起来,这个人呢,一上岁数这个脑 ...

  4. 001_Three.js中的跨域问题

    001_Three.js中的跨域问题 [情景描述]: 在初始化模型,引入字体和纹理皮肤图片的时候,由于跨域问题,出现了以下提示: Access to image at 'file:///F:/User ...

  5. JS中的跨域问题

    一.什么是跨域? 1.定义:跨域是指从一个域名的网页去请求另一个域名的资源.比如从www.baidu.com 页面去请求 www.google.com 的资源.但是一般情况下不能这么做,它是由浏览器的 ...

  6. js中的跨域方法总结

    什么是跨域? 浏览器的安全策略,只要协议,域名,端口有任何一个不同,就被当做不同的域. 下面对http://www.qichedaquan.com的同源检测 http://www.qichedaqua ...

  7. JS 中的跨域请求

    跨域请求并不仅仅只是 Ajax 的跨域请求,而是对于一个页面来说,只要它请求了其他域名的资源了,那么这个过程就属于跨域请求了. 比如,一个带有其他域名的 src 的 <img> 标签,以及 ...

  8. js中的跨域

    因为javascript的同源策略,导致它普通情况下不能跨域,直到现在,我还是不能完全理解js跨域的几种方法,没办法,只能慢慢学习,慢慢积累,这不,几天又在园里看到一篇博文,有所收获,贴上来看看; 原 ...

  9. 【原创】Vue.js 中 axios 跨域访问错误

    1.假如访问的接口地址为 http://www.test.com/apis/index.php  (php api 接口) 2.而开发地址为http://127.0.0.1:8080,当axios发起 ...

随机推荐

  1. 【HDU 5382】 GCD?LCM! (数论、积性函数)

    GCD?LCM! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total ...

  2. android 滑动冲突

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 通过move事件的 拦截. 在滑动组件中,重写 在拦截触摸事件的时候  这个方法, 然后 ...

  3. 获取设备IP地址

    腾讯的IP地址API接口地址:http://fw.qq.com/ipaddress返回的是数据格式为: 1 var IPData = new Array(“58.218.198.205″,”" ...

  4. jquery开发表格插件项目之知识点累积 二

    $.addClass() 增加样式 $.removeClass() 去除样式 $.toggleClass() 单击增加样式,再单击取消样式 $.hasClass() 判断是否存在样式,存在返回true ...

  5. Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem C. Cargo Transportation 暴力

    Problem C. Cargo Transportation 题目连接: http://opentrains.snarknews.info/~ejudge/team.cgi?SID=c75360ed ...

  6. Keil debugging techniques and alternative printf (SWO function)

    One of the basic needs of the embedded software development through the terminal to output debugging ...

  7. Serial Wire Debug (SWD) Interface -- PSoc5

    PSoC 5 supports programming through the serial wire debug (SWD) interface. There are two signals in ...

  8. lex yacc flex bison

    lex与yacc是两个在Unix下的分别作词法分析和语法分析的工具, Linux对应flex与bison. windows:http://sourceforge.net/projects/unxuti ...

  9. hdu 2546 饭卡(背包)

      设饭卡余额为total 此题经分析 可以得出:要求选出一些饭菜 时消费量尽量接近total-5元 然后再买一个饭菜 以达到透支... 可以证明 最后买的那个饭菜是饭菜中价值最大的. 证明 设a1 ...

  10. 在ASP.NET MVC控制器中获取链接中的路由数据

    在ASP.NET MVC中,在链接中附加路由数据有2种方式.一种是把路由数据放在匿名对象中传递: <a href="@Url.Action("GetRouteData&quo ...