关于ajax

69 阅读5分钟

传统请求

传统请求有哪些?

  1. 浏览器地址栏输入url
  2. 超链接
  3. form表单submit提交
  4. 使用js代码发送请求

传统请求的缺点

  1. 页面全部刷新导致用户体验感较差
  2. 用户体验感有空白期,因为会先清空旧页面,再展示新页面,当服务器响应时间较长时,页面会展示空白

那么如何实现页面的局部刷新呢?ajax可以实现

什么是ajax

Ajax即Asynchronous Javascript And XML(异步JavaScript和XML)在 2005年被Jesse James Garrett提出的新术语,用来描述一种使用现有技术集合的‘新’方法,包括: HTML 或 XHTML, CSS, JavaScript, DOM, XML, XSLT, 以及最重要的XMLHttpRequest。 [3]  使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面,这使得程序能够更快地回应用户的操作

--- 百度百科

ajax概述

  1. ajax不能称为一种技术,它是多种技术的综合产物
  2. ajax可以让那个浏览器发送一种特殊请求,这种请求可以是异步的
  3. ajax可能使用XML、JSON字符串或者纯文本字符串来传输数据
  4. ajax可更新网页部分内容,实现局部刷新
  5. ajax可做到同一个网页同时发送多个请求

ajax是如何实现页面的局部刷新的?

XMLHttpRequest对象

  1. XMLHttpRequest对象是ajax的核心对象
  2. XMLHttpRequest对象是现代浏览器的内置对象
  3. 创建XMLHttpRequest对象,var xhr = new XMLHttpRequest()
  4. XMLHttpRequest对象的方法:
    // 取消请求
    abort() 
    // 获取所有响应头字段
    getAllResponseHeaders()
    // 获取响应头字段
    getResponseHeader()
    // 开启通道
    open(method,URLasync)
    // 发送get请求
    send()
    // 发送post请求
    send(string)
    // 设置请求头字段
    setRequestHeader()
  1. XMLHttpRequest对象的属性:
    //readystate改变时的回调函数
    onreadystatechange
    // 记录XMLHttpRequest对象状态
    // 0:请求未初始化,1:服务器连接已建立,2:请求已收到,3:正在处理请求,4:请求已完成且响应已就绪
    readystate
    // 传输数据格式是字符串时,用此属性获取数据
    responseText
    // 传输数据格式是XML时,用此属性获取数据
    responseXML
    // http请求状态码
    status
    // http请求状态文字
    statusText

发送get请求

    let username = 'xf'
    let age = 18
    // 创建实例对象
    var xhr = new XMLHttpRequest()
    // 注册回调函数
    xhr.onreadystate  = function(){}
    // 打开通道,url?后是get请求的参数,&连接多个参数
    xhr.open('GET',‘/a?username=’+username+'&age='+age,true)
    // 发送请求
    xhr.send()

发送post请求

    let username = 'xf'
    let age = 18
    // 创建实例对象
    var xhr = new XMLHttpRequest()
    // 注册回调函数
    xhr.onreadystate  = function(){}
    // 打开通道
    xhr.open('POST',‘/a‘,true)
    // post要传递参数必须设置这个请求头字段,设置头必须在通道打开后
    xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')
    // 发送请求
    xhr.send(‘username=’+username+'&age='+age)

ajax的同步请求和异步请求

同步请求?

两个ajax请求,请求2要在请求1结束后才能发送

open()方法的第三个参数指定该请求是同步还是异步

xhr.open(method,url,false)该请求发送后,其他请求要等该请求结束后才能发送

异步请求?

两个ajax请求。可以同时并发,无需等待对方结束

xhr.open(method,url,true)该请求发送后不影响其他请求的发送

跨域问题

什么是跨域

浏览器有一种安全策略:同源策略,协议、域名、端口三个都一样就是同源的,其中有一个不一样就是非同源的,不同源之间的请求可能会跨域

跨域出现的根本原因:跨域的时候,不允许共享同一个XMLHttpRequest对象,因为共享同一个XMLHttpRequest对象是不安全的,同源可以共享XMLHttpRequest对象

不会跨域的情况(不涉及到XMLHttpRequest对象)

  1. 超链接
  2. form表单发送请求
  3. window.location.href/document.location.href
  4. script标签src加载js
  5. img的src加载图片资源

ajax请求跨域解决方案

  1. 设置响应头字段,Access-Control-Allow-Origin

核心原理:跨域访问的资源允许你访问

    response.setHeader('Access-Control-Allow-origin','具体允许的站点‘ 或者 *) // *:全部
  1. jsonp:json with padding(带填充的json)

    jsonp不是一个真正的ajax请求,但是可以局部刷新,借助了script标签可以跨域的特点来实现

    具体实现:

    • 前端定义一个回调函数
    • script标签中的src写要请求的后端接口
    • 后端接受请求后,响应一段js代码(函数调用)
    • 前端接收到响应数据后,执行该js代码(调用定义的回调函数,回调函数里的参数就是后端返回的查询到的数据)

简单代码实现:

前端代码

    <script type='text/javascript'>
        // 回调函数,data就是后端返回的数据
        function getInfo(data){
            console.log(data)
        }
    </script>
    // 请求后得到后端响应内容(‘func(数据)’),执行该js代码(调用回调函数)
    <script type='text/javascript' scr="/a?func=getInfo"></script>

后端代码:

    String func = request.getParameter('func')
    response.getWriter().print(func+'(要返回的数据)'
  1. jQuery封装的jsonp
  2. 代理机制
同源策略是浏览器的安全策略,服务器之间的请求是不会跨域的,
所以可以使用一个代理服务器,向同源的代理服务器发请求,代理服务器再向目标服务器去请求,
目标服务器查询到数据后,返回给代理服务器,代理服务器拿到数据后返回给浏览器,
使用的代理服务器和浏览器是同源的,没有跨域,代理服务器和目标服务器之间不存在跨域问题,因此解决了跨域问题
  1. nginx反向代理
本质上也是使用了代理机制来完成ajax的跨域,只需要修改一个nginx配置即可