AJAX跨域总结

概述

  什么是ajax

  它是一种用于创建快速动态网页的技术,通过后台与服务器进行少量数据交换(请求后端数据),ajax可以使网页实现异步更新,即在不更新整个网页的情况下,进行部分网页更新,减少用户的等待时间,加快响应。

  AJAX = 异步 JavaScript 和 XML。AJAX 是一种用于创建快速动态网页的技术。

  XmlHttpRequest对象

  XMLHttpRequest 对象所有的是ajax的基础,XMLHttpRequest 用于在后台与服务器的数据交互 目前所有的浏览器都支持XMLHttpRequest。

  1.XmlHttpRequest对象的主要方法
    a. void open(String method,String url,Boolen async) ------------ 用于创建请求
  
       参数:
           method: 请求方式(字符串类型),如:POST、GET、DELETE...
           url:    要请求的地址(字符串类型)
           async:  是否异步(布尔类型),一般填true
 
    b. void send(String body) -------------------------------------- 用于发送请求
 
        参数:
            body: 要发送的数据(字符串类型)
 
    c. void setRequestHeader(String header,String value)-------------用于设置请求头
 
        参数:
            header: 请求头的key(字符串类型)
            vlaue:  请求头的value(字符串类型)
 
    d. String getAllResponseHeaders() -------------------------------获取所有响应头
 
        返回值:
            响应头数据(字符串类型)
 
    e. String getResponseHeader(String header)-----------------------获取响应头中指定header的值
 
        参数:
            header: 响应头的key(字符串类型)
 
        返回值:
            响应头中指定的header对应的值
 
    f. void abort()-------------------------------------------------终止请求

  2.XmlHttpRequest对象的主要属性
    a. Number readyState
         状态值(整数)
         详细:
              0-未初始化,尚未调用open()方法;
              1-启动,调用了open()方法,未调用send()方法;
              2-发送,已经调用了send()方法,未接收到响应;
              3-接收,已经接收到部分响应数据;
              4-完成,已经接收到全部响应数据;
 
    b. Function onreadystatechange
         当readyState的值改变时自动触发执行其对应的函数(回调函数)
 
    c. String responseText
         服务器返回的数据(字符串类型)
 
    d. XmlDocument responseXML
         服务器返回的数据(Xml对象)
 
    e. Number states
         状态码(整数),如:200、404...
 
    f. String statesText
         状态文本(字符串),如:OK、NotFound...

  跨域

  JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。那什么是跨域呢,简单地理解就是因为JavaScript同源策略的限制,a.com域名下的js无法操作b.com或是c.a.com域名下的对象。

  当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域。不同域之间相互请求资源,就算作“跨域”

  跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。

构建原生ajax

注意:

  XmlHttpRequest支持:
    IE7+, Firefox, Chrome, Opera, etc.
    IE6, IE5不支持XmlHttpRequest,所以使用ActiveXObject("Microsoft.XMLHTTP")对象实现。

  第一步:获得XMLHttpRequest对象
  第二步:设置状态监听函数
  第三步:open一个连接,true是异步请求
  第四部:send一个请求,可以发送一个对象和字符串,不需要传递数据发送null
  第五步:在监听函数中,判断readyState=4&&status=200表示请求成功
  第六步:使用responseText、responseXML接受响应数据,并使用原生JS操作DOM进行显示

    var xhr = null;
    if(XMLHttpRequest){
        xhr = new XMLHttpRequest();
    }else{
        xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }
    // 定义回调函数
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            // 已经接收到全部响应数据,执行以下操作
            var data = xhr.responseText;
            alert(data);
        }
    };
    // 指定连接方式和地址----文件方式//默认异步请求 true
    //xhr.open('get', "/test", true);
    xhr.open('POST', "/test", true);
    // 设置请求头
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
    // 发送请求
    //xhr.send();
    xhr.send('n1=1;n2=2;');

  平时我们用的最多的还是jQuery的ajax,jQuery其实就是一个JavaScript的类库,其将复杂的功能做了上层封装,使得开发者可以在其基础上写更少的代码实现更多的功能(想要了解)。

  其他,类似vue的axios是通过promise实现对ajax技术的一种封装。就像jQuery实现ajax封装一样。(了解axios

ajax的跨域请求

  浏览器同源策略并不是对所有的请求均制约:

    制约: XmlHttpRequest
    无效: img、iframe、script等具有src属性的标签

  那么如有解决跨域请求的问题呢?下面提供了几种方法实现跨域请求。

  1.JSONP

  利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 数据。JSONP请求一定需要对方的服务器做支持才可以。

  JSONP优点是兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持get方法具有局限性。

  (1)JSONP的流程

  声明一个回调函数,其函数名(如fn)当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的data)。

  创建一个<script>标签,把那个跨域的API数据接口地址,赋值给script的src,还要在这个地址中向服务器传递该函数名(可以通过问号传参:?callback=fn)。

  服务器接收到请求后,需要进行特殊的处理:把传递进来的函数名和它需要给你的数据拼接成一个字符串,例如:传递进去的函数名是fn,它准备好的数据是fn([{"name":"jianshu"}])。

  最后服务器把准备的数据通过HTTP协议返回给客户端,客户端再调用执行之前声明的回调函数(fn),对返回的数据进行操作。

    <script type="text/javascript">
        function fn(data) {
            alert(data.msg);
        }
    </script>
    <script type="text/javascript" src="http://crossdomain.com/jsonServerResponse?jsonp=fn"></script>

  其中 fn 是客户端注册的回调的函数,目的获取跨域服务器上的json数据后,对数据进行在处理。
  最后服务器返回给客户端数据的格式为:

    fn({ msg:'this  is  json  data'})

  (2)jQuery的jsonp请求

emsp; JSONP都是GET和异步请求的,不存在其他的请求方式和同步请求,且jQuery默认就会给JSONP的请求清除缓存。

    $.ajax({
        url:"http://crossdomain.com/jsonServerResponse",
        dataType:"jsonp",
        type:"get",//可以省略
        jsonpCallback:"fn",//->自定义传递给服务器的函数名,而不是使用jQuery自动生成的,可省略
        jsonp:"jsonp",//->把传递函数名的那个形参callback变为jsonp,可省略
        success:function (data){
             console.log(data);}
        });

  2.CORS

  1.CORS原理
  整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

  2.CORS优缺点
  CORS要求浏览器(>IE10)和服务器的同时支持,是跨域的根本解决方法,由浏览器自动完成。
  优点在于功能更加强大支持各种HTTP Method,缺点是兼容性不如JSONP。
  只需要在服务器端做一些小小的改造即可:

    header("Access-Control-Allow-Origin:*");
    header("Access-Control-Allow-Methods:POST,GET");

  例如:网站http://localhost:63342/ 页面要请求http://localhost:3000/users/userlist 页面,userlist页面返回json字符串格{name: 'Mr.Cao', gender: 'male', career: 'IT Education'}

  JAVA后台配置

    JAVA后台配置只需要遵循如下步骤即可:
    第一步:获取依赖jar包下载 cors-filter-1.7.jar, java-property-utils-1.9.jar 这两个库文件放到lib目录下。(放到对应项目的webcontent/WEB-INF/lib/下)
    第二步:如果项目用了Maven构建的,请添加如下依赖到pom.xml中:

    <dependency>
        <groupId>com.thetransactioncompany</groupId>
        <artifactId>cors-filter</artifactId>
        <version>[ version ]</version>
    </dependency>

  在响应头上添加Access-Control-Allow-Origin属性,指定同源策略的地址。同源策略默认地址是网页的本身。只要浏览器检测到响应头带上了CORS,并且允许的源包括了本网站,那么就不会拦截请求响应。

  3.使用HTML5中新引进的window.postMessage方法来跨域传送数据

  window.postMessage(message,targetOrigin) 方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。

  调用postMessage方法的window对象是指要接收消息的那一个window对象,该方法的第一个参数message为要发送的消息,类型只能为字符串;第二个参数targetOrigin用来限定接收消息的那个window对象所在的域,如果不想限定域,可以使用通配符 * 。

  需要接收消息的window对象,可是通过监听自身的message事件来获取传过来的消息,消息内容储存在该事件对象的data属性中。

  上面所说的向其他window对象发送消息,其实就是指一个页面有几个框架的那种情况,因为每一个框架都有一个window对象。在讨论第二种方法的时候,我们说过,不同域的框架间是可以获取到对方的window对象的,而且也可以使用window.postMessage这个方法。下面看一个简单的示例,有两个页面

    //发送信息页面 http://localhost:63342/index.html
    <html lang="en">  
    <head>  
        <meta charset="UTF-8">  
        <title>跨域请求</title>   
    </head>  
    <body>  
        <iframe src="http://localhost:3000/users/reg" id="frm"></iframe>  
        <input type="button" value="OK" onclick="run()">  
    </body>  
    </html>  
    <script>  
       function  run(){  
            var frm=document.getElementById("frm");  
            frm.contentWindow.postMessage("跨域请求信息","http://localhost:3000");  
       }  
    </script>

    //接收信息页面 http://localhost:3000/message.html
    window.addEventListener("message",function(e){  //通过监听message事件,可以监听对方发送的消息。
        console.log(e.data);  
    },false);

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容

  • 什么是跨域 跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实...
    Yaoxue9阅读 1,290评论 0 6
  • 什么是跨域 跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实...
    他方l阅读 1,062评论 0 2
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,457评论 1 45
  • 题目1.什么是同源策略? 同源策略(Same origin Policy): 浏览器出于安全方面的考虑,只允许与本...
    FLYSASA阅读 1,715评论 0 6
  • 1. 什么是跨域 跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScri...
    cbw100阅读 6,320评论 2 86