AJAX

作者: darkTi | 来源:发表于2018-02-27 23:59 被阅读0次

如何发请求?

  • 用form可以发post或get请求,但是但是会刷新页面或新开页面
  • 用 a 可以发 get 请求,但是也会刷新页面或新开页面
  • 用 img 可以发 get 请求,但是只能以图片的形式展示
  • 用 link 可以发 get 请求,但是只能以 CSS、favicon 的形式展示
  • 用 script 可以发 get 请求,但是只能以脚本的形式运行

所以急需一种API可以满足以下两个要求:

  1. get、post、put、delete 请求都行
  2. 想以什么形式展示就以什么形式展示

微软的突破

IE 5 率先在 JS 中引入 ActiveX 对象(API),使得 JS 可以直接发起 HTTP 请求。随后 Mozilla、 Safari、 Opera 也跟进了,取名 XMLHttpRequest,并被纳入 W3C 规范。 1.png

AJAX

  • Jesse James Garrett 将如下技术取名叫做 AJAX(Async JavaScript And XML):异步的 JavaScript 和 XML
  1. 使用 XMLHttpRequest 发请求
  2. 服务器返回 XML 格式的字符串(现在都使用JSON来代替XML)
  3. JS 解析 XML,并更新局部页面
  • AJAX就是用JS去发请求
  • 响应的第四部分是字符串,可以用 JSON 语法表示一个对象,也可以用 JSON 语法表示一个数组,还可以用 XML 语法,还可以用 HTML 语法,还可以用 CSS 语法,还可以用 JS 语法,还可以用自创的语法
  • 示例
myButton.addEventListener('click',(e)=>{
  let request = new XMLHttpRequest()
  request.open('get','/xxx')//配置request
  request.send()
  setInterval(()=>{console.log(request.readyState)},1)
})
结果: 2.png

XMLHttpRequest.readyState 属性返回一个 XMLHttpRequest 代理当前所处的状态


3.png
图2中没有出现0、2、3是因为他们运行太快,没有捕捉到;每一次都会按照0~4的状态来运行。
由此可见,每毫秒来捕捉也无法得到所有的状态,那么有没有一个属性只要状态发生变化就通知我?有的。
request.onreadystatechange 

如何使用 XMLHttpRequest

myButton.addEventListener('click',(e)=>{
  let request = new XMLHttpRequest()
  request.open('get','/xxx')//配置request
  request.send()
  request.onreadystatechange = ()=>{
    if(request.readyState === 4){
      console.log('请求响应完毕了')
      if(request.status >= 200 && request.status < 300){
        console.log('说明请求成功')
        console.log(request.responseText)
        let string = request.responseText
        let object = window.JSON.parse(string)
        //把符合JSON语法的字符串转换成JS对应的值,JSON.parse是浏览器提供的
        console.log(typeof object)
        console.log(object)
      }
    }
  }
})
//后端代码
else if(path==='/xxx'){
    response.statusCode = 200
    response.setHeader('Content-Type', 'text/json;charset=utf-8')
    response.setHeader('Access-Control-Allow-Origin', 'http://frank.com:8001')
    response.write(`
    {
      "note":{
        "to": "小谷",
        "from": "方方",
        "heading": "打招呼",
        "content": "hi"
      }
    }
    `)
    response.end()
  }

原生JS写一个AJAX

let request = new XMLHttpRequest()//声明
  request.open('get','/xxx')//配置request
  request.send()//发送
  request.onreadystatechange = ()=>{
    if(request.readyState === 4){
      if(request.status >= 200 && request.status < 300){
        let string = request.responseText
        let object = window.JSON.parse(string)//解析
      }
    }
  }

JSON

  1. JSON是由Douglas Crockford(道格拉斯克罗克福德)构想设计的数据交换语言,它是一门新的语言,与JavaScript不一样
  2. JS VS JSON 4.png

同源策略

  • 即只有 协议+端口+域名 一模一样才允许发 AJAX 请求,否则浏览器上的任何网页都可被随意盗取信息
  1. http://baidu.com 可以向 http://www.baidu.com 发 AJAX 请求吗? 不可以
  2. http://baidu.com:80 可以向 http://baidu.com:81 发 AJAX 请求吗? 不可以
    要保持一模一样才能发AJAX请求
  • 如果想要请求别的域名,那么就给它的后台打电话,通过两种方式处理①JSONP(但它不能发POST请求);②CORS跨域;(用哪种方法都可以)

CORS跨域

  • Cross-Origin Resource Sharing(跨站资源共享)
  • 只需在需要共享的那个域名下加上一句代码
    response.setHeader('Access-Control-Allow-Origin', 'http://frank.com:8001')

就是告诉浏览器http://frank.com:8001这个网站是我的朋友,你不要拦它,可以让它读我的内容

AJAX的所有功能

  • 客户端的JS发起请求(浏览器上的)
  • 服务端的JS发送响应(Node.js上的)
  1. JS 可以设置任意请求 header
    第一部分 request.open('get', '/xxx') //浏览器默认get请求是不显示第四部分的
    第二部分 request.setRequestHeader('Content-Type','x-www-form-urlencoded')
    第四部分 request.send('a=1&b=2') //请求体
  2. JS 可以获取任意响应 header
    第一部分 request.status //状态码
    request.statusText //状态码的文字解释
    第二部分 request.getResponseHeader('Content-Type') //获取指定的响应头
    request.getAllResponseHeaders() //获取全部的响应头
    第四部分 request.responseText //响应体
    至此,HTTP是如何请求响应的,就大致了解了:
    ①客户端通过AJAX设置请求头,发送请求到服务器端(服务器端需要指定端口)
    ②服务器端设置响应并发送到客户端(客户端不需要指定端口)

用jQuery封装AJAX

window.jQuery = function(nodeOrSelector){
  let nodes = {}
  nodes.addClass = function(){}
  return nodes
}
window.jQuery.ajax = function(url,method,body,success,fail){
  let request = new XMLHttpRequest()
  request.open(method,url)//配置request
  request.onreadystatechange = ()=>{
    if(request.readyState === 4){
      if(request.status >= 200 && request.status < 300){
       success.call(undefined,request.responseText)
      }else if(request.status >= 400){
        fail.call(undefined,request)
      }
    }
  }
  request.send(body)
}

window.$ = window.jQuery

myButton.addEventListener('click',(e)=>{
  window.jQuery.ajax(
   '/xxx',
   'post',
   'a=1&&b=2',
   ()=>{console.log(1)},
   ()=>{console.log(2)}
  )
})

但是上面最大的不足就是ajax函数中参数太多,容易造成忘记每个参数代表什么,所以需要作出优化,把所有参数转换成一个对象传进去

window.jQuery.ajax = function(options){
  
  let url = options.url
  let method = options.method
  let body = options.body
  let success = options.success
  let fail = options.fail
  let headers = options.headers
......
}

利用ES6的解构赋值语法优化参数

window.jQuery.ajax = function(options){
  let {url,method,body,success,fail,headers} = options
......
}

继续优化

window.jQuery.ajax = function({url,method,body,success,fail,headers}){
......
}

Promise

  • 因为成功需要回调成功函数,失败要回调失败函数,但是每个库的成功失败回调函数名是不一样的,例如image.onload(成功),image.onerror(失败),我们不可能一一地去查每个库回调函数的名字,所以就引入promise(promise是window下的全局属性),利用promise的then属性。
then(()=>{},()=>{}) //成功执行第一个函数,失败执行第二个函数
  • 利用jQuery的promise属性(不要忘记引入jQuery)
myButton.addEventListener('click',(e)=>{
  $.ajax(
   {url:'/xxx',
   method:'post',
   headers:{
     'Content-Type':'x-www-form-urlencoded',
     'doudou':'18'
    }   
   }).then(
     (text)=>{console.log(text)},
     (request)=>{console.log(request)}
    )
})
  • 自己定义promise来封装AJAX
window.jQuery = function(nodeOrSelector){
  let nodes = {}
  nodes.addClass = function(){}
  nodes.html = function(){}
  return nodes
}
window.$ = window.jQuery
window.Promise = function(fn){
  return {
    then: function(){}
  }
}

window.jQuery.ajax = function({url,method,body,headers}){
  return new Promise(function(resolve, reject){ //这六个单词是最重要的
    let request = new XMLHttpRequest()
    request.open(method,url)//配置request
    for(let key in headers){ //遍历对象中的属性
      let value = headers[key]
      request.setRequestHeader(key,value)
    }
    request.onreadystatechange = ()=>{
      if(request.readyState === 4){
        if(request.status >= 200 && request.status < 300){
         resolve.call(undefined,request.responseText)
        }else if(request.status >= 400){
          reject.call(undefined,request)
        }
      }
    }
    request.send(body)
  })

}
myButton.addEventListener('click',(e)=>{
  let promise = window.jQuery.ajax(
   {url:'/xxx',
   method:'post',
   headers:{
     'Content-Type':'x-www-form-urlencoded',
     'doudou':'18'
    }   
   })
   promise.then(
     (text)=>{console.log(text)},
     (request)=>{console.log(request)}
    )
})

相关文章

  • AJAX

    主要内容: ajax 是什么、原生ajax 写法和jQuery ajax写法。 AJAX 是什么 ajax,即As...

  • JavaScript进阶知识点--AJAX及JSON

    AJAX 关于 AJAX 什么是 AJAX AJAX 的全称是 Asynchronous JavaScript a...

  • HTML5权威指南 | 第五部分 高级功能

    三十二、使用AJAX(上) Ajax起步: 使用Ajax事件: Ajax请求的错误处理: 中止Ajax请求: 三十...

  • ajax学习笔记

    Ajax学习笔记 Ajax简介 1. Ajax是什么? Ajax : Asynochronous javascri...

  • AJAX

    一、简介 AJAX菜鸟教程 什么是 AJAX ? AJAX = 异步 JavaScript 和 XML。 AJAX...

  • js之AJAX复习

    异步交互和同步交互 什么是Ajax? Ajax的工作原理。 Ajax包含的技术: Ajax的缺陷: Ajax的核心...

  • 复习jQuery - ajax

    jQuery ajax - ajax() 方法 $.ajax({ url:'oo.php', ...

  • jQuery中Ajax请求的使用和四个步骤示例

    ajax() 方法用于执行 AJAX(异步 HTTP)请求,所有的 jQuery AJAX 方法都使用 ajax(...

  • ajax

    1、什么是ajax? 2、ajax的原理 3、ajax的核心对象 4、ajax的优点: ajax的缺点: 被jqu...

  • ajax

    Ajax 1 - 请求纯文本 Ajax 2 - 请求JSON数据 Ajax 3 - 请求Github接口 Ajax...

网友评论

      本文标题:AJAX

      本文链接:https://www.haomeiwen.com/subject/mzhmxftx.html