Contents
  1. 1. 一、Ajax
    1. 1.0.1. 1. Ajax是什么?
      1. 1.0.1.0.1. AJAX 是无需刷新页面就能从服务器获得数据的一种方法。
  2. 1.0.2. 2. Ajax的优缺点
  3. 1.0.3. 3. Ajax 最大的特点是什么?
  4. 1.0.4. 4. 简述Ajax的过程
  5. 1.0.5. 5. Ajax的交互模型
  • 2. 二、详解Ajax
    1. 2.0.1. 1. XMLHttpRequest
      1. 2.0.1.0.1. 方法是:
      2. 2.0.1.0.2. 虽然名字中包含XML 但是Ajax通信与数据格式无关;这种技术就是无需刷新页面即可从服务器取得数据,但不一定是XML数据
  • 2.0.2. 2. 使用XHR 对象
  • 2.0.3. 2. XHR的用法
    1. 2.0.3.0.1. 要发送特定的请求,必须调用send()方法
      1. 2.0.3.0.1.1. 对于同步请求
      2. 2.0.3.0.1.2. 对于异步请求
    2. 2.0.3.0.2. 在onreadystatechange事件处理程序中使用XHR对象没有使用this对象的原因是什么?
  • 2.0.4. 3. HTTP头部信息
    1. 2.0.4.0.1. 设置自定义请求头部信息
  • 2.0.5. 4. Get请求
    1. 2.0.5.0.1. 查询字符串中的每个参数的名称和值都必须使用 encodeURIComponent 进行编码,才能放到url末尾;而且所有的名-值对都必须有和号(&)分割
  • 2.0.6. 5. Post请求
  • 3. XMLHttpReauest 2级
    1. 3.0.1. 1. formData
    2. 3.0.2. 2. 超时设定
      1. 3.0.2.0.1. timeout属性,表示请求在等待响应多少毫秒之后就会终止,
  • 3.0.3. 3. overrideMimeType方法
  • 3.0.4. 4. 进度事件
  • 3.0.5. 5. 跨源资源共享 CORS
    1. 3.0.5.1. CORS的几种解决方案
      1. 3.0.5.1.0.1. Preglighted Requests 透明服务器验证机制(使用自定义头部,get或者post之外的方法)
  • 3.0.6. 6. 其他跨域技术
    1. 3.0.6.0.0.1. 1. 图像Ping(只能用于浏览器和服务器之间的单向通信)
    2. 3.0.6.0.0.2. 2. JSONP(被包含在函数调用中的JSON)
    3. 3.0.6.0.0.3. 3. Comet P588
    4. 3.0.6.0.0.4. 考点轮询
    5. 3.0.6.0.0.5. 4. SSE 服务器发送事件 P590
    6. 3.0.6.0.0.6. 5. Web Sockets P591
  • @TOC

    一、Ajax

    1. Ajax是什么?

    Ajax 全称是 asynchronous Javascript and XML, 即异步 javaScript 和XML,用于在web 页面中实现异步数据交互,实现页面局部刷新。

    AJAX 是无需刷新页面就能从服务器获得数据的一种方法。

    是一种用于创建快速动态网页的技术。
    通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
    传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。
    有很多使用 AJAX 的应用程序案例:新浪微博、Google 地图、开心网等等。

    2. Ajax的优缺点

    • 优点:
      可以使得页面不重载全部内容的情况下加载局部内容,降低数据传输量,避免用户不断刷新或者跳转页面,提高用户体验。
      1. 通过异步模式,提升了用户体验
      2. 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用
      3. Ajax在客户端运行,承担了一部分本来由服务器承担的工作吗,减少了大用户量下的服务器负载
    • 缺点:
      1. ajax 不支持浏览器back 按钮
      2. 安全问题ajax 暴露了与服务器交互的细节
      3. 对搜索引擎支持比较弱
      4. 破坏了程序的异常机制

    3. Ajax 最大的特点是什么?

    Ajax 可以实现异步通信效果,实现页面局部刷新,带来更好的用户体验,按需获取数据,节约宽带资源。

    4. 简述Ajax的过程

    1. 创建XMLHttpRequest 对象,也就是创建一个异步调用对象
    2. 创建一个新的HTTP请求,并指定该HTTP请求的方法,URL及验证信息
    3. 设置响应HTTP请求状态变化的函数
    4. 发送HTTP请求
    5. 获取异步调用返回的数据
    6. 使用JavaScript 和DOM 实现局部刷新

    5. Ajax的交互模型

    在这里插入图片描述
    浏览器的普通交互方式
    在这里插入图片描述
    浏览器的ajax交互方式
    在这里插入图片描述

    二、详解Ajax

    1. XMLHttpRequest

    Ajax 的核心对象是XMLHttpRequest对象,简称XHR

    方法是:
    1. 使用XHR 对象获得新数据
    2. 通过DOM 将数据插入到页面中
      虽然名字中包含XML 但是Ajax通信与数据格式无关;这种技术就是无需刷新页面即可从服务器取得数据,但不一定是XML数据

    2. 使用XHR 对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    function createXHR(){
    if(typeof XMLHttpRequest != "undefined"){
    return new XMLHttpRequest(); //对原生XHR对象的支持
    }else if(typeof ActiveXObject != "undefined"){
    if(typeof arguments.callee.activeXString != "string"){
    //callee 是 arguments 对象的一个属性。它可以用于引用该函数的函数体内当前正在执行的函数
    var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"],
    i,len;
    for(i=0, len=versions.length; i<len; i++){
    try{
    new ActiveXObject(versions[i]);
    arguments.callee,activeXString = versions[i];
    break;
    }catch(ex){
    //跳过
    }
    }
    }
    return new ActiveXObject(arguments.callee.activeXString)
    }else{
    throw new Error("No XHR object available")
    }
    }
    var xhr = new createXHR(); //创建XHR对象

    这个函数的作用:

    1. 先检测原生XHR对象是否存在,如果存在则返回它的新实例
    2. 如果袁姗姗对象不存在,则检测ActiveX对象
    3. 如果以上两种对象都不存在,则抛出一个错误

    2. XHR的用法

    在使用XHR对象时,要调用的第一个方法是 open(),他接收3个参数

    1. 要发送请求的的类型
    2. 请求的URL;
    3. 表示是否异步发送请求的布尔值
    1
    2
    xhr.open("get", "example.php", false)
    //这行代码将会启动一个针对example.php 的get请求

    说明:

    1. URL 相对于执行这行代码的当前页面(也可以使用绝对路径)
    2. 调用open() 方法并不会真正发送数据,只是启动一个请求以备发送

    注意:
    只能向同一个域中使用相同的端口和协议的URL发送请求。如果URL与启动请求的页面有任何差别,都会引发安全错误。

    要发送特定的请求,必须调用send()方法
    对于同步请求
    1
    2
    xhr.open("get", "example.php", false)
    xhr.send(null)

    这里的send接收一个参数,作为请求主体发送的数据。
    如果不需要通过请求主体发送数据,则必须传入null(因为这个参数对有些浏览器来说是必需的)
    调用send之后,请求就会被分派到服务器。
    由于这次请求是同步的,js代码会等到服务器响应之后再继续执行。在收到响应后,响应的数据会自动填充XHR对象的属性,相关属性简介如下:

    • responseText:作为响应主体被返回的文本
    • responseXML:如果响应的内容类型是“text/xml”或者“qpplication/xml”,这个属性中将保存包含着响应数据的XML DOM 文档
    • status:响应的HTTP状态
    • statusText:http状态的说明

    在接到响应后,第一步是检查status 属性,以确定响应已经成功返回(一般来说,200作为成功的标志)。
    此时,responseText 属性的内容已经就绪,而且在内容类型正确的情况下,responseXML 也应该能够访问了。此外。304表示请求的资源并没有被修改,可以直接使用浏览器中缓存的版本,当然也意味着响应是有效的。为确保接收到合适的响应,应该进行检查

    1
    2
    3
    4
    5
    6
    7
    8
    9
    xhr.open("get", "example.php", false)
    xhr.send(null)
    if((xhr.status>=200 && xhr.status<300) || xhr.status == 304){
    alert(xhr.responseText);
    }else{
    alert("Request was unsuccessful:"+ xhr.status)

    }
    }

    根据返回的状态码,这个例子可能会显示由服务器返回的内容,也有可能会显示一条错误消息。
    所以建议通过检测status来决定下一步的操作,不要依赖statusText(跨浏览器使用不太可靠)。

    无论内容类型是什么,响应主体的内容都会保存到responseText 属性中;而对于非XML 数据而言,responseXML 的属性将为NULL。

    对于异步请求

    可以利用XHR 对象的readyState 属性(该属性表示请求/响应过程的当前活动阶段),取值如下:

    • 0:未初始化。尚未调用open方法
    • 1:启动。已经调用了open方法,但未调用send 方法
    • 2 :发送。已经调用了send 方法,但未接收到响应
    • 3:接收:已经接收到部分响应的数据
    • 4:完成。已经接收到全部响应数据,而且已经可以在客户端使用了(只对4的值感兴趣,因为这时候所有数据都已经准备就绪)

    只要readyState 属性的值从一个值变成另一个值,就会触发一次readystatechange 事件。可以利用这点检测每次状态变化后readyState 的值。

    必须在调用open 之前指定onreadystatechange事件才能确保跨浏览器兼容性。P574

    在onreadystatechange事件处理程序中使用XHR对象没有使用this对象的原因是什么?

    onreadystatechange事件处理程序的作用域问题。如果使用this 对象,在有的浏览器中会导致函数执行失败,或者导致错误发生。因此,使用实际的XHR对象实例变量是较为可靠的一种方式。

    3. HTTP头部信息

    XHR 对象提供了两种头部信息

    • 请求头部
    • 响应头部

    默认情况下在发送XHR 请求的同时,还会发送以下头部信息:

    1. Accept:浏览器能处理的内容类型
    2. Accept-Encoding:浏览器能处理的压缩编码
    3. Accept-Language:浏览器当前设置的语言
    4. Accept-Charset:浏览器能显示的字符集
    5. Connection:浏览器与当前服务器之间连接的类型
    6. Cookie:当前页面设置的任何cookie
    7. Host:发出请求的页面所在的域
    8. Referer:发出请求的压面的URL,
    9. User-Agent:浏览器的用户代理字符集
    设置自定义请求头部信息

    setRequestHeader() 可以自定义设置请求头部信息。
    这个方法接收两个参数:

    • 头部字段的名称
    • 头部字段的值

    要成功发送请求头部信息,必须在调用open方法之后且调用send方法之前调用setRequestHeader()
    例子详见P575

    服务器在接收到这种自定义的头部信息之后,可以执行相应的后续操作。
    建议使用自定义头部字段名称,不要使用浏览器正常发送的字段名称,否则有可能会影响服务器的响应(有的浏览器允许开发人员重写默认的头部信息,但有的浏览器不允许这样做)

    调用XHR 对象的 getResponseHeader()方法并传入头部字段名称,可以取得相应的响应头部信息。而调用getAllResponseHeader()方法,则可以取得一个包含所有头部信息的长字符串(例子详见P576)

    4. Get请求

    get是最常见的请求类型,常用于向服务器查询某些信息
    对于XHR而言,位于传入的URL 末尾的查询字符串 必须经过正确的编码才行。

    查询字符串中的每个参数的名称和值都必须使用 encodeURIComponent 进行编码,才能放到url末尾;而且所有的名-值对都必须有和号(&)分割

    P576详见代码

    5. Post请求

    通常用于向服务器发送应该被保存的数据
    Post 请求应该把数据作为请求的主体提交,而get 请求传统上不是这样的
    post 请求可以包含非常多的数据,而且格式不限。

    1. 初始化post

      1
      xhr.open("open", "example.php", true)
    2. 向send 方法传入某些数据
      最初的设计是为了处理XML, 因此可以传入XML DOM 文档,传入的文档经序列化之后将作为请求主体被提交到服务器。
      使用XHR 模仿表单提交:

      1. 将Content-Type头部信息设置为application/x-www-form-urlencode,也就是表单提交时的内容相同
      2. 一适当格式创建一个字符串
      3. post数据的格式与查询字符串格式相同,如果需要将表单的数据进行序列化,则使用serialize()

    如果不设置content-type 头部信息,那么发送给服务器的数据就不会出现在 $_POST超级全局变量中,这时候要访问同样的数据,就必须借助于$HTTP_RAW_POST_DATA

    XMLHttpReauest 2级

    1. formData

    为序列化表单以及创建与表单格式相同的数据带来了便利
    使用append创建formData对象

    append() 方法接收两个参数

    • 键 对应表单字段的名字
    • 值 对应字段中包含的值

    使用formdata 的方便之处是不必明确的在XHR对象上设置请求头部,XHR 对象能够识别传入的数据类型是FormData 的实例

    2. 超时设定

    timeout属性,表示请求在等待响应多少毫秒之后就会终止,

    再给timeout 设置一个数值后,在规定的时间内浏览器还没有收到响应吗,那么就会触发timeout事件,进而会调用ontimeout 事件处理程序

    注意:
    请求终止时,会调用ontimeout事件处理程序,但此时readyState 可能已解决改变为4了,这意味着会调用 onreadystatechange 事件处理程序,如果在超时终止之后再访问status 属性就会导致错误。为了避免浏览器报告错误,可以将检查status 属性的语句封装在一个try-catch语句中

    3. overrideMimeType方法

    用于重写XHR的MIME类型(返回响应的MIME类型决定了XHR对象如何处理它)P580

    4. 进度事件

    详情:https://www.w3cmm.com/ajax/progress-events.html P581

    • loadstart:在接收到相应数据的第一个字节时触发。
    • progress:在接收相应期间持续不断触发。
    • error:在请求发生错误时触发。
    • abort:在因为调用abort()方法而终止链接时触发。
    • load:在接收到完整的相应数据时触发。
    • loadend:在通信完成或者触发error、abort或load事件后触发。

    5. 跨源资源共享 CORS

    使用自定义的HTTP头部让浏览器与服务器进行沟通 ,从而决定请求或响应是成功还是失败

    • 需要加上一个额外的Origin 头部(其中包含请求页面的源信息:协议、域名和端口),以便服务器根据这个头部信息来决定是否给予响应
    • 使用Access-Control-Allow-Origin头部中回发相同的源信息,表示服务器可以接受
      如果没有这个头部,或者这个头部但源信息不匹配,浏览器就会驳回请求,正常情况下,浏览器会处理请求

    CORS的几种解决方案

    CORS背后的基本思想是使用自定义的HTTP头部允许浏览器和服务器相互了解对方,从而决定请求或响应成功与否.

    Preglighted Requests 透明服务器验证机制(使用自定义头部,get或者post之外的方法)

    Access-Control-Allow-Origin:指定授权访问的域
    Access-Control-Allow-Methods:授权请求的方法(GET, POST, PUT, DELETE,OPTIONS等)

    一:简单的自定义CORSFilter / Interceptor
    适合设置单一的(或全部)授权访问域,所有配置都是固定的,特简单。也没根据请求的类型做不同的处理

    在web.xml 中添加filter

    1
    2
    3
    4
    5
    6
    7
    8
    <filter>
    <filter-name>cros</filter-name>
    <filter-class>cn.ifengkou.test.filter.CORSFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>cros</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>

    新增CORSFilter 类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Component
    public class CORSFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    response.addHeader("Access-Control-Allow-Origin", "*");
    response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
    response.addHeader("Access-Control-Allow-Headers", "Content-Type");
    response.addHeader("Access-Control-Max-Age", "1800");//30 min
    filterChain.doFilter(request, response);
    }
    }

    Access-Control-Allow-Origin只能配置 或者一个域名*
    比如配置了192.168.56.130,那么只有192.168.56.130 能拿到数据,否则全部报403异常

    1
    response.addHeader("Access-Control-Allow-Origin", "http://192.168.56.130");

    还有两种,详见原文https://www.cnblogs.com/sloong/p/cors.html

    6. 其他跨域技术

    1. 图像Ping(只能用于浏览器和服务器之间的单向通信)

    是与服务器进行简单。单向的跨域通信的一种方式(请求的数据是通过字符串形式发送的)
    图像ping 常用于跟踪用户点击页面或动态广告曝光次数

    缺点:

    1. 只能发送get请求
    2. 无法访问服务器的响应文本
      2. JSONP(被包含在函数调用中的JSON)
      由两部分组成
    • 回调函数:是响应到来时应该在页面回调的函数(回调函数的名字一般是在请求中指定的)
    • 数据:传入回调函数中的JSON数据

    jsonp 是通过script 元素来使用的,使用时为src 属性指定一个跨域URL(这里的script和img 元素类似,都有能力不受限制从其他域加载资源)
    因为jsonp 是有效的js代码,所以在请求完成后,即在jsonp 响应加载到页面中,就会立即执行

    JSONP和图像Ping相比的优点:
    能够直接访问响应文本,支持在浏览器和服务器之间的双向通信

    不足:

    1. JSONP 是从其他域中加载代码执行。如果其他域不安全,很可能在响应中夹带一些恶意代码,而此时除了完全放弃JSONP调用之外,没有办法追究。因此在使用不是你自己运维的web服务时,一定得保证它安全可靠。
    2. 要确定JSONP 请求是否失败并不容易。(开发人员不得不使用计时器检测指定时间内是否收到了响应,但是就算这样也不能尽如人意,毕竟不是每一个用户上网的速度和带宽都是一样)
    3. Comet P588
    考点轮询

    Ajax是一种页面向服务器请求数据的技术,而Comet 则是一种服务器向页面推送数据的技术。
    Comet 能够让信息近乎实时的被推送到页面上(适合体育分数和股票报价)

    有两种方式实现Comet:

    • 长轮询:浏览器定时的向服务器发送请求,看看有没有更新的数据(等待发送响应)
      短轮询:立即发送响应,无论数据是否有效
      轮询的优势就是所有浏览器都支持
    • 流:生命周期内只使用一个HTTP连接,具体来说就是:浏览器向服务器发送一个请求,而服务器保持连接打开,然后周期性的向浏览器发送数据
      4. SSE 服务器发送事件 P590
      是围绕只读Comet 交互推出的API ,用于创建到服务器的单向连接,服务器通过这个连接可以发送任意数量的数据
      服务器响应的MIME 类型必须是 text/event-stream,而且是以浏览器的js API 能解析的格式输出
      SSE 支持长短轮询和HTTP流,而且能在断开连接的时候自动确定何时重新连接
      5. Web Sockets P591
      目标是在一个单独的持久连接上提供全双工,双向通信

    SSE:只读取服务器
    Web Socket:双向通信

    Contents
    1. 1. 一、Ajax
      1. 1.0.1. 1. Ajax是什么?
        1. 1.0.1.0.1. AJAX 是无需刷新页面就能从服务器获得数据的一种方法。
    2. 1.0.2. 2. Ajax的优缺点
    3. 1.0.3. 3. Ajax 最大的特点是什么?
    4. 1.0.4. 4. 简述Ajax的过程
    5. 1.0.5. 5. Ajax的交互模型
  • 2. 二、详解Ajax
    1. 2.0.1. 1. XMLHttpRequest
      1. 2.0.1.0.1. 方法是:
      2. 2.0.1.0.2. 虽然名字中包含XML 但是Ajax通信与数据格式无关;这种技术就是无需刷新页面即可从服务器取得数据,但不一定是XML数据
  • 2.0.2. 2. 使用XHR 对象
  • 2.0.3. 2. XHR的用法
    1. 2.0.3.0.1. 要发送特定的请求,必须调用send()方法
      1. 2.0.3.0.1.1. 对于同步请求
      2. 2.0.3.0.1.2. 对于异步请求
    2. 2.0.3.0.2. 在onreadystatechange事件处理程序中使用XHR对象没有使用this对象的原因是什么?
  • 2.0.4. 3. HTTP头部信息
    1. 2.0.4.0.1. 设置自定义请求头部信息
  • 2.0.5. 4. Get请求
    1. 2.0.5.0.1. 查询字符串中的每个参数的名称和值都必须使用 encodeURIComponent 进行编码,才能放到url末尾;而且所有的名-值对都必须有和号(&)分割
  • 2.0.6. 5. Post请求
  • 3. XMLHttpReauest 2级
    1. 3.0.1. 1. formData
    2. 3.0.2. 2. 超时设定
      1. 3.0.2.0.1. timeout属性,表示请求在等待响应多少毫秒之后就会终止,
  • 3.0.3. 3. overrideMimeType方法
  • 3.0.4. 4. 进度事件
  • 3.0.5. 5. 跨源资源共享 CORS
    1. 3.0.5.1. CORS的几种解决方案
      1. 3.0.5.1.0.1. Preglighted Requests 透明服务器验证机制(使用自定义头部,get或者post之外的方法)
  • 3.0.6. 6. 其他跨域技术
    1. 3.0.6.0.0.1. 1. 图像Ping(只能用于浏览器和服务器之间的单向通信)
    2. 3.0.6.0.0.2. 2. JSONP(被包含在函数调用中的JSON)
    3. 3.0.6.0.0.3. 3. Comet P588
    4. 3.0.6.0.0.4. 考点轮询
    5. 3.0.6.0.0.5. 4. SSE 服务器发送事件 P590
    6. 3.0.6.0.0.6. 5. Web Sockets P591