1、跨域请求:
 Cross Domain Request:跨域名的HTTP请求,浏览器从某个域名下的资源访问了另一域名下的另一资源(协议、域名或是端口号不同);
 ①浏览器允许跨域请求的情形:
  <img>、<link>、<script>、<iframe>
 ②禁止跨域请求的情形:
  XHR——浏览器默认出于安全考虑,禁止XHR跨域请求;
 ③相关名词及解决方案:
  a、相同域:两个具有相同的协议(如:http)、相同的端口(如:80)、相同的host(主机名),即为相同域,否则构成跨域;
  b、file协议:用于访问本地计算机中的文件;
  c、同源策略:跨域之间的脚本是隔离的,一个域中的脚本不能访问、操作另一个域的绝大部分属性和方法;同源策略应对一些特殊情况做处理,例:限制file协议下脚本的访问权限,本地的HTML文件在浏览器中是通过file协议打开的,若脚本能通过file协议访问到硬盘上的其他任意文件,就会出现安全隐患;
  d、单向跨域之JSONP:JSON with Padding;
   原理:由于HTML中的script标签可以加载执行其它域的javascript,所以可以通过script标记动态加载其它域的资源;
   实现:在pageB中以javascript的形式声明pageA所需的数据,然后在pageA中用script标签将 pageB加载进来,JSONP在此基础上加入回调函数,pageB加载完后会执行pageA中定义的函数,所需数据以参数形式传递给该函数;
   限制:JSONP适合在受信任的双方传递数据,否则易被第三方脚本篡改页面内容,截获敏感数据;
   代码:
   function handleResponse(response){
       console.log('The responsed data is: '+response.data);
   }
   var script = document.createElement('script');
   script.src = 'http://www.baidu.com/json/?callback=handleResponse';
   document.body.insertBefore(script, document.body.firstChild);
   /*handleResonse({"data": "zhe"})*/
   //原理如下:
   //当我们通过script标签请求时
   //后台就会根据相应的参数(json,handleResponse)
   //来生成相应的json数据(handleResponse({"data": "zhe"}))
   //最后这个返回的json数据(代码)就会被放在当前js文件中被执行
   //至此跨域通信完成
  e、单向跨域之flash URLLoader:
   原理:flash有自己的安全策略,服务器可以通过crossdomain.xml文件声明能被哪些域的SWF文件访问,SWF也可以通过API确定自身能被哪些域的SWF加载,跨域访问时,可借助flash发送HTTP请求;
   实现:先修改域中crossdomain.xml,将其加入白名单,然后通过Flash URLLoader发送HTTP请求,通过Flash API将响应结果传递给javascript;
   限制:不支持IOS;
  f、单向跨域之Access Control:
   原理:浏览器发送跨域的HTTP请求,请求包含一个Access-Control-Allow-Origin的HTTP响应头部,该响应头声明了请求域的可访问权限;
   实现:给被跨域访问的资源添加响应消息头部,设定允许来自某个域名下的页面访问当前页面:header('Access-Control-Allow-Origin:http://xxx.xx');
   限制:少数浏览器支持(Firefox、Chrome通过XMLHttpRequest,IE8通过XDomainRequest发送请求);
  g、单向跨域之window.name:
   原理:当window的location变化,重新加载,name属性依然保持不变;
   实现:在pageA中用iframe加载其它域的pageB,在pageB中用javascript把需要传递的数据赋值给window.name,iframe加载完成后,pageA修改iframe的地址为同域的一个地址,即可读出window.name的值;
   代码:
   请求代理:
   <head>
       <script>
      function proxy(url, func){
        var isFirst = true,
            ifr = document.createElement('iframe'),
            loadFunc = function(){
              if(isFirst){
                ifr.contentWindow.location = 'http://a.com/cs1.html';
                isFirst = false;
              }else{
                func(ifr.contentWindow.name);
                ifr.contentWindow.close();
                document.body.removeChild(ifr);
                ifr.src = '';
                ifr = null;
              }
            };

ifr.src = url;
        ifr.style.display = 'none';
        if(ifr.attachEvent) ifr.attachEvent('onload', loadFunc);
        else ifr.onload = loadFunc;

document.body.appendChild(iframe);
      }
    </script>
   </head>
   <body>
     <script>
       proxy('http://www.baidu.com/', function(data){
         console.log(data);
       });
     </script>
   </body>
   响应:
   <script>
       window.name = '要传送的内容';
   </script>
  h、单向跨域之server proxy:
   原理:在数据提供方没有提供对JSONP或window.name协议的支持,也没有对其它域开放访问权限时,可使用server proxy(服务器代理)方式抓取数据,跨域的HTTP请求在服务器端进行,客户端不用产生跨域的Ajax请求;
   实现:在服务器配置一个代理,将Ajax请求绑定到这个代理路径下,然后由这个代理发送Http请求去访问文件;
   限制:该跨域方式不需要和目标资源签订协议,带有侵略性,另需对该代理实施一定程度的保护,如限制他人使用或使用频率;
  i、双向跨域之document.domain:
   原理:同域策略认为域和子域属于不同的域,修改document的domain属性为同一host,可以在域和子域或不同子域间通信;
   实现:将不同子域document的domain属性修改为同一host,浏览器会认为它们处于同一域下,此时即可互相调用对方的method来通信;
   代码:
   请求:
   document.domain = 'a.com';
   var ifr = document.createElement('iframe');
   ifr.src = 'http://www.script.a.com/b.html';
   ifr.display = none;
   document.body.appendChild(ifr);
   ifr.onload = function(){
       var doc = ifr.contentDocument || ifr.contentWindow.document;
       //在这里操作doc,也就是b.html
       ifr.onload = null;
   };
   响应:
   document.domain = 'a.com';
  j、双向跨域之FIM:
   原理:Fragment Identiter Messaging,父窗口与iframe可以相互读写URL,URL中“#”号及其后面的字符被称为frag,它一般用于浏览器锚点定位,HTTP请求中不会携带frag,每个window通过改变其他window的location来发送消息,并通过监听自己的URL变化来接收消息;
   限制:这种方式通信会产生不必要的浏览器历史记录,且有些浏览器不支持onhashchange事件,需要用轮询来获知URL的改变,另URL在浏览器下有长度限制,制约了每次传送的数据量;
  k、双向跨域之Flash LocalConnection:
   原理:Flash API中有LocalConnection类,该类允许两个SWF之间进行通信,SWF可以播放在独立的Flash Player或者AIR中,也可以嵌套在HTML页面或者PDF中;
   实现:在不同域的HTML页面各自嵌套一个SWF来相互传递数据;
   限制:数据量有40kb的大小限制,且过程复杂,实用性不强;
  l、双向跨域之window.postMessage:
   HTML5定义的新方法,可跨window通信,在较旧浏览器中无法使用;
   代码:
   请求:
   <iframe id="ifr" src="b.com/index.html"></iframe>
   <script type="text/javascript">
    window.onload = function() {
        var ifr = document.getElementById('ifr');
        var targetOrigin = 'http://b.com';  // 若写成'http://b.com/c/proxy.html'效果一样
                 // 若写成'http://c.com'就不会执行postMessage了
        ifr.contentWindow.postMessage('I was there!', targetOrigin);
    };
   </script>
   响应:
   <script type="text/javascript">
       window.addEventListener('message', function(event){
           // 通过origin属性判断消息来源地址
           if (event.origin == 'http://a.com') {
               alert(event.data);    // 弹出"I was there!"
               alert(event.source);  // 对a.com、index.html中window对象的引用
                     // 但由于同源策略,这里event.source不可以访问window对象
           }
       }, false);
   </script>
  m、双向跨域之Cross Frame:
   原理:FIM的变种,借助空白iframe,不会产生多余浏览器历史记录,也不需要轮询URL的改变;域中pageA和空白代理页proxyA,另一个域pageB和其空白代理页proxyB,pageA向pageB发送消息时页面创建隐藏的iframe,iframe的src指向proxyB,并把message作为URL frag;pageB和proxyB是同域,iframe加载完成后,pageB可以获得iframe的URL,解析出message,并移除iframe;反向同理;
   限制:Opera无法使用,但可使用window.postMessage;
  n、动态创建script:
   function loadScript(url, func) {
     var head = document.head || document.getElementByTagName('head')[0];
     var script = document.createElement('script');
     script.src = url;

script.onload = script.onreadystatechange = function(){
       if(!this.readyState || this.readyState=='loaded' || this.readyState=='complete'){
         func();
         script.onload = script.onreadystatechange = null;
       }
     };

head.insertBefore(script, 0);
   }
   window.baidu = {
     sug: function(data){
       console.log(data);
     }
   }
   loadScript('http://suggestion.baidu.com/su?wd=w',function(){console.log('loaded')});
   //我们请求的内容在哪里?
   //我们可以在chorme调试面板的source中看到script引入的内容
  o、Web Socket:
   原理:web sockets是一种浏览器的API,它的目标是在一个单独的持久连接上提供全双工、双向通信,在JS创建了web socket之后,会有一个HTTP请求发送到浏览器以发起连接。取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为web sockt协议;
   代码:
   var socket = new WebSockt('ws://www.baidu.com');//http->ws; https->wss
   socket.send('hello WebSockt');
   socket.onmessage = function(event){
       var data = event.data;
   }
   限制:只有在支持web socket协议的服务器上才能正常工作;
2、jQuery中发起JSONP请求的方法:
 ①$.getJSON两种方法:
  a、使用XHR接收服务器端返回的JSON响应:
   $.getJSON('x.php',function(obj){});
  b、使用script标签执行服务器返回的script响应——JSONP:
   $.getJSON('http://其他域名/x.php?callback=?',doResponse);
 ②$.ajax的两种方法:
  a、使用XHR接收服务器端返回的响应:
   $.ajax({});
  b、使用script标签执行服务器返回的script响应——JSONP:
   $.ajax({
    type:'GET',
    url:'x.php',
    data:{k:v},
    dataType:'jsonp',//设定服务器端返回JSONP数据
    success:fn
   });

* 本篇内容部分自网上整理而来,请原作者勿怪!

Ajax_05之跨域请求的更多相关文章

  1. Laravel中的ajax跨域请求

    最近接触Laravel框架ajax跨域请求的过程中遇到一些问题,在这里做下总结. 一开始发起ajax请求一直报500错误,搜索相关资料后发现Laravel要允许跨域请求可以加入Cors中间件,代码如下 ...

  2. 跨域请求——WebClient通过get和post请求api

    AJAX不可以实现跨域请求,经过特殊处理才行.一般后台可以通过WebClient实现跨域请求~ //get 请求        string url = string.Format("htt ...

  3. 原生js封装ajax,实现跨域请求

    描述: 需要ajax跨域请求,用cors跨域方案.服务端设置: header('Access-Control-Allow-Origin: http://front.ls-la.me'); header ...

  4. 关于试用jquery的jsonp实现ajax跨域请求数据的问题

    我们在开发过程中遇到要获取另一个系统数据时,就造成跨域问题,这就是下文要说的解决办法: 先我们熟悉下json和jsonp的区别: 使用AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交 ...

  5. 【JavaScript】--重点解析之跨域请求

    JSON JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. JSON是用字符串来表示Javascript对象,例如可以在django中发送一个JSON格式 ...

  6. 利用CORS实现跨域请求(转载)

    跨域请求一直是网页编程中的一个难题,在过去,绝大多数人都倾向于使用JSONP来解决这一问题.不过现在,我们可以考虑一下W3C中一项新的特性--CORS(Cross-Origin Resource Sh ...

  7. 浅谈linux 下,利用Nginx服务器代理实现ajax跨域请求。

    ajax跨域请求对于前端开发者几乎在任何一个项目中都会用到,众所周知,跨域请求有三种方式: jsonp; XHR2 代理: jsonp: 这种应该是开发中是使用的最多的,最常见的跨域请求方法,其实aj ...

  8. 解决ajax跨域请求 (总结)

    ajax跨域请求,目前已用几种方法实现:   1)用原生js的xhr对象实现.                var url="http://freegeoip.net/json/" ...

  9. 【笔记】Asp.Net WebApi对js POST带参数跨域请求的支持方案

    先说下需求:在原来的WebApi项目中增加对js跨域的请求支持,请求方式:以POST为主,webapi路由规则根据原项目需求修改如下: public static void Register(Http ...

随机推荐

  1. 活动助手Beta用户试用报告

    用户试用报告 1.面向参与者用户 1.1 日常参加各类学习(水综测)活动中,有没有遇到以下问题: (1) 信息来源混乱,不知道靠不靠谱 (2) 每次报名都要重新填写自己的学号手机号,有时候填错了就没综 ...

  2. Linq的分页

    真有趣. C#里面的List对象.set对象,都可以直接使用Linq(这是因为,它们都实现了接口IEnumable?),比如说:Where().OrderBy()什么的.假如有点SQL基础的人,一看这 ...

  3. RPC原理及RPC实例分析

    在学校期间大家都写过不少程序,比如写个hello world服务类,然后本地调用下,如下所示.这些程序的特点是服务消费方和服务提供方是本地调用关系. 1 2 3 4 5 6 public class ...

  4. Kafka replication

    Kafka replication kafka_replication_detailed_design_v2.pdf kafka Detailed Replication Design V3 Apac ...

  5. 体育游戏中的Player类

    最近在做一个棒球的游戏,开始感觉还是挺酷炫的,但是其实做法挺朴实的,想象中的球员是多么智能,这样那样的,其实只是表象. 关于球员的类是游戏里非常重要的部分,这个玩意怎么写呢,可以这样写...... 棒 ...

  6. Master-Slave通用基础框架

    一.设计目的 设计出一个通用的Master-Slave基础框架,然后可以基于这个框架来实现特定的业务需求,比如实现多节点并行计算.分布式处理等. 二.设计理念 基于经典的命令模式,Master和Sla ...

  7. Ubuntu 14.04(amd64)安装Oracle11g XE(x64)

    下载Oracle安装包 下载地址:Oracle Database Express Edition 11g Release 2 for Linux x64 安装办法 1、建立oracle用户及属主 ad ...

  8. Python 爬虫1——爬虫简述

    Python除了可以用来开发Python Web之后,其实还可以用来编写一些爬虫小工具,可能还有人不知道什么是爬虫的. 一.爬虫的定义: 爬虫——网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区 ...

  9. HTML5新特性——HTML 5 Canvas vs. SVG

    Canvas 和 SVG 都允许您在浏览器中创建图形,但是它们在根本上是不同的. SVG SVG 是一种使用 XML 描述 2D 图形的语言. SVG 基于 XML,这意味着 SVG DOM 中的每个 ...

  10. getComputedStyle的应用

    后面有例子,所以把HTML,CSS样式写在前面 HTML结构: <div id="myDiv" style="background-color: lightseag ...