网页异步请求--ajax

226 阅读5分钟

ajax:异步的 js 和 xml,通过 ajax 可以在浏览器中向服务器发送异步请求,ajax 不是一门新的编程语言 是将现有的标准组合的一种新方式(依然还是在使用js),最大的优势:无需刷新获取数据

ajax的优缺点

优点:
1、可以无需刷新浏览器与服务器端进行通信
2、允许用户根据事件来更新部分页面内容
缺点:
1、没有浏览历史,不能倒退
2、存在跨域问题(同源)
3、SEO(搜索引擎优化)不友好 (例如爬虫爬不到,数据是通过异步向服务器请求的)

ajax-http协议请求报文与响应文本结构体

HTTP协议[超文本传输协议],协议详细规定了浏览器与万维网服务器之间通信的规则。
浏览器-------请求(专业别名:请求报文)---->服务器------响应(专业别名:响应报文)----->浏览器
##请求报文
  `请求报文的格式和参数` 四部分
  请求行(分3部分)  请求类型(get/post/...)/URL路径/HTTP协议版本
  请求头  格式 键值对格式  key:value
  空行
  请求体  uname=admin&password=admin
  (get请求时请求体为空在url中展示出来,post请求时请求体为参数不为空)
##响应报文
响应行   HTTP版本/响应状态码/响应状态字符串
响应头
空行
响应体  后端数据

在浏览器开发者中的NetWork中就可以看到

ajax结构

// 1、创建ajax对象
const xhr = new XMLHttpRequest()
// 2、初始化,设置请求方法和url
xhr.open("GET",'url')
// 3、发送
xhr.send()
//4、事件绑定 处理服务器返回结果
xhr.onreadystatechange = function(){
    // readystate 是 xhr 对象中的属性,表示状态
    0 (刚开始 readystate 就为0)
    1 (表示open方法调用完毕)
    2 (表示send方法调用完毕)
    3 (表示服务端返回了部分接口)
    4 (表示服务端返回了所有请求)
  
    // 判断在 状态为4的时候 获取数据
    if(xhr.readyState === 4){
        // 判断响应状态码 200 404 403 ...
        if(xhr.status >= 200 && xhr.status <300){
           // 处理结果 响应行 响应头 空体 响应体
            console.log(xhr.status) //状态
            console.log(xhr.statusText) //状态字符串
            console.log(xhr.getAllResponseHeaders())//所有响应头
            console.log(xhr.response)//响应体
           }
      }
}

传参

//GET 在发送时添加参数
xhr.open('GET', 'url/?a=100&b=200') 

//POST 在send中添加
xhr.send('a:100&b:200')

一些响应请求的设置

设置请求头

// 在初始化 设置类型和url后一行添加
xhr.setRequestHeader('自定义响应头名称/定义好的','自定义内容/定义好的内容')
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')

//一般会把身份校验信息放在这里传递到服务器,由服务器来对信息进行提取对用户进行效验。

响应数据设置

//现在基本都是使用JSON传递数据,所以在接收的时候需要做处理
//可以手动 JSON.parse(xhr.response)
//自动转换 xhr.responseType = 'json' 写在发送请求下面

响应超时设置

//写在发送请求下面
xhr.timeout = 秒
//请求超过这秒则报错,超时回调
xhr.ontimeout = function(){...}
//网络异常回调
xhr.onerror = function(){...}

取消(中断)ajax请求

//在请求情况下还是会被中断
xhr.abort()

jquery请求方式

script src = cdn.bootcdn.....
`get`
$('button').eq(0).click(function(){
    $.get('http://local:端口',{参数},callback,'响应体类型 - json')
})
`post`
$('button').eq(1).click(function(){
    $.get('http://local:端口',{参数},callback,'响应体类型 - json')
})
`通用 all`
$('button').eq(2).click(function(){
    $.ajax({
        url:'http://local:端口',
        参数 data:{a:100},
        请求类型 type:'GET/POST/...',
        响应体结果 dataType:'json',
        超时 timeout:2000,   
        自定义响应头 headers:{a:100} 需要后端进行请求头的配置   
        成功的回调 success:function(data){
                 //处理函数
                  }   
        失败回调 error:function(err){
                // 处理函数
                  }
    })
})

fecth的请求

//fetch返回的是一个Promise对象
btn.onclick = funtion(){
    fetch('url',{
        //配置对象
        method:'GET',
        headers:{},
        请求体 body:'username=admin&...'
    }).then(res =>{
        return res.text() // 把返回的值变为文本类型
        return res.json() //返回json类型 这两个都是fetch里面的方法
    })
}

跨域

页面是向服务器请求的而页面中的操作也是向同一个服务器发送请求的,单台服务器的内存是有上限的,所以才有多台服务器存储数据,而就有了跨服务请求数据的模式,考虑到安全的问题所以需要进行验证,而跨域则是这些问题的由来;

同源策略 是浏览器的一种安全策略;
同源是指协议、域名、端口号 必须完全相同,反之为跨域;

解决跨域的两种方式

jsonp

//JSONP(SJON with Padding) 是一个非官方的跨域解决方案,只支持get请求
//JSONP的工作模式
//在网页有一些标签天生具有跨域能力,比如img、link、iframe、script;
//JSONP就是利用script标签的跨域能力来发送请求的。
//通过script去获取后端的脚本
//例
script src='https://...' //请求数据

//实现步骤
  //1、在客户端(自己的html/js文件)创建一个js函数,用来接收服务端返回的数据。
  function onResponse(data){
      //处理 追加到元素中也可以打印也可以
  }
  //2、在客户端动态插入 script 标签执行请求。
  const script = document.createElement('script')
  script.src = 'protocal://domain:port/path?callback=onResponse'
  document.body.appendChild(script)
  //3、服务端将数据和 js 回调函数名拼接为函数调用的字符串并返回给客户端。
  app.get('/path', function(request, response) {
    var data = getData()
    var callback = request.query.callback
    var result = `${callback}(${JSON.stringify(data)});`
    response.send(result)
  })
  //4、客户端接收到 script 标签响应并自动执行回调函数。
  
//实际:
//  1、前端调用后端时传递给后端数据的处理函数callback
//  2、后端收到处理函数callback之后,进行数据库查询等操作,将后端要传递给前端的数据(一般为json格式)放入callback函数的()中并返回(实际上就是由后端动态生成一个前端可用的js脚本)
//  3、html页面在脚本文件加载后,自动执行脚本
//  4、完成了整个jsonp请求。

  
  `优缺点`
   //优:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都 可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果
   //缺:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题,切很明显的需要后端工程师配合才能完成。,动态插入的 script 脚本可能被注入恶意代码。

jquery-jsonp

点击事件(){
    $.getJSONP('url?callback=?',function(data){})
}

//后端
let str = JSONP.stringify(data)
let cb = 请求参数.query.callback
响应.end(`${cb}(${str})`)

CORS
CORS(Cross-Origin Resource Sharing)跨域资源共享。官方推出 特点:不需要在客户端做任何操作,完全在服务器执行,支持get和post。跨域资源共享标准新增加一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访问那些资源。

CORS的工作方式:
CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后对响应放行。
CORS的使用
客户端正常操作 服务端添加响应头 response.setHeader("Access-Control-Allow-Origin","允许的访问的网页。例如http://127.0.0.1:5000。一般使用*表示所有网页都通配")

感想
现在大部分使用项目基本很少会使用 ajax,但在一些老的项目中ajax的使用频率还是很高的,所以回顾一下