js中各种跨域问题实战小结

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

这是因为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);

3

4       }

5

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实现跨域

时间: 2024-10-12 22:25:12

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

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

这里接上篇:js中各种跨域问题实战小结(一) 后面继续学习的过程中,对上面第一篇有稍作休整.下面继续第二部分: -->5.利用iframe和location.hash -->6.window.name跨域实现 利用iframe和location.hash实现跨域 想必有很多人像我之前一样,或许只知道上面文中所说的那几种方法.所以,我刚了解到可以用iframe和location.hash来实现跨域的时候,我会想,为什么他们可以实现.iframe是什么,有什么特性,location.hash是什么

JS 中的跨域请求

跨域请求并不仅仅只是 Ajax 的跨域请求,而是对于一个页面来说,只要它请求了其他域名的资源了,那么这个过程就属于跨域请求了. 比如,一个带有其他域名的 src 的 <img> 标签,以及页面中引入的其他第三方的 CSS 样式等. 对于 img 以及 CSS 而言,跨域请求本身并没有更多的安全问题,因为这些请求都属于只读请求,并不会对源资源造成副作用. 而如果跨域请求是从脚本里面发出去的,由于脚本具有高度灵活性,浏览器出于安全考虑,会根据同源策略来限制它的功能,使得正常情况下,脚本只能请求同源

JS中的跨域问题

跨域访问出错信息:No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9100' is therefore not allowed access. The response had HTTP status code 400. 1.跨域的概念 跨域是指从一个域名的网页去请求另一个域名的资源.比如从www.baidu.com 页面去请求 www.g

php中ajax跨域请求---小记

php中ajax跨域请求---小记 前端时间,遇到的一个问题,情况大约是这样: 原来的写法: 前端js文件中: $.ajax({ type:'get', url:'http://wan.xxx.com/xxx.js', success:function(data){ ......... } }) 很简单的一个ajax请求:后面在做迁移的时候,由于系统目录的安排,js文件放到了,img.xxx.com域名下,这样就设计到了跨域问题,于是就改成了这样: $.ajax({ type:'get', ur

vue.js学习之 跨域请求代理与axios传参

vue.js学习之 跨域请求代理与axios传参 一:跨域请求代理 1:打开config/index.js module.exports{ dev: { } } 在这里面找到proxyTable{},改为这样: proxyTable: { '/api': { target: 'http://121.41.130.58:9090',//设置你调用的接口域名和端口号 别忘了加http changeOrigin: true, pathRewrite: { '^/api': ''//这里理解成用'/ap

ASP.NET MVC中设置跨域

ASP.NET MVC中设置跨域 1.什么是跨域请求 js禁止向不是当前域名的网站发起一次ajax请求,即使成功respone了数据,但是你的js仍然会报错.这是JS的同源策略限制,JS控制的并不是我们网站编程出现了问题.客户端(网页)和后台编程都可以有效解决这个问题.客户端可以通过JSONP来完成跨域访问:在ES6中为了解除同源策略问题,想出一个办法:当被请求网站为响应头respone添加了一个名为Access-Control-Allow-Origin的header,设置其值等于发起请求网站的

跨域问题实战 2

跨域问题实战 2 背景 由于整个项目提供出去的API都不是跨域的只是个别是需要跨域的,所以再上一次跨域问题实战中,自己是直接再controller层其中需要提供出去跨域的方法里设置了HttpServletResponse.setHeader("Access-Control-Allow-Origin","*").而且上次提供出去的只是一次简单的get请求,而不是复杂请求.但是呢,这次的需求是记录用户行为日志的一次跨域请求,也就是说是一次post请求.其中就涉及到htt

【JS】AJAX跨域-被调用方与调用方解决方案(二)

解决跨域问题 跨域问题说明,参考[JS]AJAX跨域-JSONP解决方案(一) 实例,使用上一章([JS]AJAX跨域-JSONP解决方案(一))的实例 解决方案三(被调用方支持跨域) 被调用方解决,基于支持跨域的解决思路,基于Http协议关于跨域的相关规定,在响应头里增加指定的字段告诉浏览器,允许调用 跨域请求是直接从浏览器发送到被调用方,被调用方在响应头里增加相关信息,返回到页面,页面能正常获取请求内容. 1.服务端增加一个过滤器(CrossFilter.java),过滤所有请求,在请求响应

ASP.NET中Cookie跨域的问题及解决代码

ASP.NET中Cookie跨域的问题及解决代码 http://www.liyumei.net.cn/post/share18.html Cookies揭秘  http://www.cnblogs.com/zhangziqiu/archive/2009/08/06/cookies-javascript-aspnet.html 最近在项目开发中遇到一个很棘手的问题,一个用户在顶级域名登录后,跳转到自己所拥有的二级域名下管理二级网站时,cookie丢失了,一直找解决办法找了整整两天,百度谷歌一大堆,