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

 
这是因为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 4562 dp ***

    题意:给出一个点p(X,Y)以及若干圆.从中选出尽可能多的圆满足:圆能且只能包含p或者原点中的一个(不能在圆上):圆之间不能相交或者相切. 链接:点我 用dp求满足条件包含一个点圆的最多数目,然后两个 ...

  2. springMvc Velocity tool 源码分析

    在公司使用pandoraboot配置了velocity tool,一直不明白官方支持的init方法没有调用,而且不支持velocity tool 1.x版本的定义(1.x和2.x的定义见下面),而另一 ...

  3. spring-boot 速成(10) -【个人邮箱/企业邮箱】发送邮件

    发邮件是一个很常见的功能,代码本身并不复杂,有坑的地方主要在于各家邮件厂家的设置,下面以qq个人邮箱以及腾讯企业邮箱为例,讲解如何用spring-boot发送邮件: 一.添加依赖项 compile ' ...

  4. 【Go命令教程】13. go tool cgo

    cgo 也是一个 Go 语言自带的特殊工具.一般情况下,我们使用命令 go tool cgo 来运行它.这个工具可以使我们创建能够调用 C 语言代码的 Go 语言源码文件.这使得我们可以使用 Go 语 ...

  5. C# Windows服务开发从入门到精通

    一.课程介绍 大家都知道如果想要程序一直运行在windows服务器上,最好是把程序写成windows服务程序:这样程序会随着系统的自动启动而启动,自动关闭而关闭,不需要用户直接登录,直接开机就可以启动 ...

  6. 大数据以及Hadoop相关概念介绍

    一.大数据的基本概念 1.1.什么是大数据 大数据指的就是要处理的数据是TB级别以上的数据.大数据是以TB级别起步的.在计算机当中,存放到硬盘上面的文件都会占用一定的存储空间,例如: 文件占用的存储空 ...

  7. 未经处理的异常:System.Net.Sockets.SocketException: 以一种访问权限不允许的方式做了一个访问套接字的尝试

    报错:未经处理的异常:System.Net.Sockets.SocketException: 以一种访问权限不允许的方式做了一个访问套接字的尝试 → 尝试以"管理员身份"运行程序, ...

  8. Mac上 python 找不到 yaml模块

    (1)  yaml http://codyaray.com/2011/12/pyyaml-using-easy_install-on-mac-os-x-lion 1.报错 ImportError: N ...

  9. 每天定时备份mysql数据库任务

    需求: 1,每天4点备份mysql数据: 2,为节省空间,删除超过3个月的所有备份数据: 3,删除超过7天的备份数据,保留3个月里的 10号 20号 30号的备份数据: #创建shell文件 vim ...

  10. 2016 移动应用质量大数据报告--转自腾讯Bugly

    2016年,在“互联网+”战略的推动下,移动互联网与越来越多传统行业的结合更加紧密,用户使用移动互联网的工作场景.生活场景.消费场景都在悄然发生着改变, 移动互联网产品在智能硬件.医疗.汽车.旅游.教 ...