http://www.javashuo.com/article/p-bbnotdik-ep.htmljavascript
http://www.cnblogs.com/yuzhongwusan/archive/2012/12/11/2812849.htmlhtml
跨域是指a页面想获取b页面资源,若是a、b页面的协议、域名、端口、子域名不一样,或是a页面为ip地址,b页面为域名地址,所进行的访问行动都是跨域的,而浏览器为了安全问题通常都限制了跨域访问,也就是不容许跨域请求资源。好比,Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面、动态网页、web服务、WCF,只要是跨域请求,一概不许 前端
一、Web页面上调用js文件时则不受是否跨域的影响(不只如此,咱们还发现凡是拥有”src”这个属性的标签都拥有跨域的能力,好比<\script>、<\img>、<\iframe>)。java
二、因而能够判断,当前阶段若是想经过纯web端(ActiveX控件、服务端代理、属于将来的HTML5之Websocket等方式不算)跨域访问数据就只有一种可能,那就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理。nginx
三、恰巧咱们已经知道有一种叫作JSON的纯字符数据格式能够简洁的描述复杂数据,更妙的是JSON还被js原生支持,因此在客户端几乎能够为所欲为的处理这种格式的数据。web
四、这样子解决方案就呼之欲出了,web客户端经过与调用脚本如出一辙的方式,来调用跨域服务器上动态生成的js格式文件(通常以JSON为后缀),显而易见,服务器之因此要动态生成JSON文件,目的就在于把客户端须要的数据装入进去。json
五、客户端在对JSON文件调用成功以后,也就得到了本身所需的数据,剩下的就是按照本身需求进行处理和展示了,这种获取远程数据的方式看起来很是像AJAX,但其实并不同。后端
六、为了便于客户端使用数据,逐渐造成了一种非正式传输协议,人们把它称做JSONP,该协议的一个要点就是容许用户传递一个callback参数给服务端,而后服务端返回数据时会将这个callback参数做为函数名来包裹住JSON数据,这样客户端就能够随意定制本身的函数来自动处理返回数据了。api
咱们看看如下几个实体, jsonp.html跨域
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <script type="text/javascript"> // 获得航班信息查询结果后的回调函数 var flightHandler = function(data){ alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。'); }; // 提供jsonp服务的url地址(不论是什么类型的地址,最终生成的返回值都是一段javascript代码) var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler"; // 建立script标签,设置其属性 var script = document.createElement('script'); script.setAttribute('src', url); // 把script标签加入head,此时调用开始 document.getElementsByTagName('head')[0].appendChild(script); </script> </head> <body> </body> </html>
对应处理jsonp请求的后端代码,核心任务就是返回一个包括json数据的函数调用js代码。这段js代码会在web客户端执行,而flightHandler函数是在前端定义的。
echo ' flightHandler({ "code": "CA1998", "price": 1780, "tickets": 5 }'
利用script标签绕过同源策略,得到一个相似如下的js函数调用,jsonpcallback是页面存在的回调方法,而数据就以函数参数的形式保存在callback函数参数中。
jsonpcallback({"Email":"zhww@outlook.com","Remark":"我来自遥远的东方"})
仅仅支持get请求
从上面的讨论咱们知道jsonp虽然能够必定程度上解决跨域的get请求数据访问问题,可是没法支持post操做。这时CORS就能够较好解决这个问题。可是CORS必须服务器配合配置来完成。
CORS的基本原理是客户端Origin头字段+服务器的如下配置实现
Access-Control-Allow-Origin: http://api.bob.com Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: FooBar Content-Type: text/html; charset=utf-8
Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: X-Custom-Header Access-Control-Allow-Credentials: true Access-Control-Max-Age: 1728000
上面已经说到,禁止跨域问题实际上是浏览器的一种安全行为,而如今的大多数解决方案都是用标签能够跨域访问的这个漏洞或者是技巧去完成,但都少不了目标服务器作相应的改变,而我最近遇到了一个需求是,目标服务器不能给予我一个header,更不能够改变代码返回个script,因此前5种方案都被我否决掉。最后由于个人网站是我本身的主机,因此我决定搭建一个nginx并把相应代码部署在它的下面,由页面请求本域名的一个地址,转由nginx代理处理后返回结果给页面,并且这一切都是同步的。